二叉树的先序,中序,后序遍历递归与非递归实现
二叉树先序遍历:
递归实现:
void PreOrderTraverse(BSTreeNode* root, int ) { if(!root) { return ; } res.push_back(root->value); PreOrderTraverse(root->left, 0); PreOrderTraverse(root->right, 0); }
非递归实现:
void PreOrderTraverse(BSTreeNode* root) { stack<BSTreeNode* > sta; sta.push(root); //BSTreeNode* temp = root; while(!sta.empty()) { BSTreeNode *node = sta.top(); sta.pop(); res.push_back(node->value); if(node->right) { sta.push(node->right); } if(node->left) { sta.push(node->left); } } }
二叉树中序遍历:
递归实现:
遍历左子树输出结点值,再输出中间值,最后遍历右子树输出节点值
vector<int> res; void InOrderTraverse(BSTreeNode* root,int n) { if(!root) { return ; } InOrderTraverse(root->left, 0); res.push_back(root->value); InOrderTraverse(root->right, 0); }
非递归实现:
void InOrderTraverse(BSTreeNode* root) { stack<BSTreeNode* > sta; sta.push(root); BSTreeNode* temp = root; while(!sta.empty()) { while(temp->left) { sta.push(temp->left); temp = temp->left; } BSTreeNode *node = sta.top(); res.push_back(node->value); sta.pop(); if(node->right) { temp = node->right; sta.push(node->right); } } }
void InOrderTraverse(BSTreeNode *root) { stack<BSTreeNode* > sta; BSTreeNode* temp = root; while(temp != NULL || !sta.empty()) { while(temp) { sta.push(temp); temp = temp->left; } if(!sta.empty()) { temp = sta.top(); res.push_back(temp->value); sta.pop(); temp = temp->right; } } }
下面是另一种写法:
vector<int> res; void InOrderTraverse(BSTreeNode* root) { if(!root) return ; stack<pair<BSTreeNode*, int>> sta; sta.push({root, 0}); BSTreeNode* temp; int times; while(!sta.empty()) { temp = sta.top().first; times = sta.top().second; sta.pop(); if(times == 0) { if(temp->right) sta.push({temp->right, 0}); sta.push({temp, times, 1}); if(temp->left) sta.push({temp->left, 0}); } else { res.push_back(temp->val); } } }
二叉树后序遍历:
递归实现:
void PostOrderTraverse(BSTreeNode* root, int) { if(!root) { return; } PostOrderTraverse(root->left, 0); PostOrderTraverse(root->right, 0); res.push_back(root->value); }
非递归实现:
第二种思路:要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子,则可以直接访问它;或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。若非上述两种情况,则将P的右孩子和左孩子依次入栈,这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。
void PostOrderTraverse(BSTreeNode* root) { stack<BSTreeNode *> sta; sta.push(root); BSTreeNode* temp = root; BSTreeNode* pre = NULL; while(!sta.empty()) { temp = sta.top(); if((!temp->left && !temp->right) || (pre != NULL) && (pre == temp->left || pre == temp->right)) { res.push_back(temp->value); sta.pop(); pre = temp; } else { if(temp->right) { sta.push(temp->right); } if(temp->left) { sta.push(temp->left); } } } }