二叉树的遍历是二叉树的众多算法的基础。主要有,前序,中序与后序。
对于以下二叉树:
前序:12354
中序:21543
后序:24531
笔者实现了三种遍历方式:
1 前序:递归版本比较简单,只需要改变push_back操作的位置即可。
vector<int> PreOrderTraverse2(TreeNode *root) { vector<int> nodes; vector<int> temp; if(root == NULL) return nodes; nodes.push_back(root->val); temp = PreOrderTraverse2(root->left); for(vector<int>::size_type i = 0 ; i != temp.size() ; ++i) nodes.push_back(temp[i]); temp = PreOrderTraverse2(root->right); for(vector<int>::size_type i = 0 ; i != temp.size() ; ++i) nodes.push_back(temp[i]); return nodes; }
(1)首先访问根节点root,先将root节点输出,压入堆栈,
(2)再考虑root节点的左子树,左子树也是一颗二叉树,重复(1)。
(3)某一步的左子树为空,那么该节点左子树已访问完毕,弹出栈顶,访问该节点的右子树,重复(1)即可。
很简单,只需要记住,在将节点压入堆栈时,该节点就已被访问,再访问完左孩子之后,再考虑右孩子所在的二叉树。
vector<int> PreOrderTraverse(TreeNode *root) { vector<int> nodes; stack<TreeNode *> s; if(root == NULL) return nodes; TreeNode *temp = root; while(temp || !s.empty()) { while(temp) { s.push(temp);//入栈之前就访问 nodes.push_back(temp->val); temp = temp->left; }//左子树访问完毕 temp = s.top(); s.pop(); temp = temp->right; } return nodes; }
vector<int> InOrderTraverse2(TreeNode *root) { vector<int> nodes; vector<int> temp; if(root == NULL) return nodes; temp = InOrderTraverse2(root->left); for(vector<int>::size_type i = 0 ; i != temp.size() ; ++i) nodes.push_back(temp[i]); nodes.push_back(root->val); temp = InOrderTraverse2(root->right); for(vector<int>::size_type i = 0 ; i != temp.size() ; ++i) nodes.push_back(temp[i]); return nodes; }
(1)首先访问根节点root,压入堆栈。
(2)访问root的左子树,重复(1)即可。
(3)如果某节点左子树为空,那么该节点输出,并考察其右子树,重复(1)即可。
PS:节点入栈使不访问,遇到节点就入栈,直到栈顶左子树访问完毕,那么将栈顶弹出,考虑右子树,重复即可。
vector<int> InOrderTraverse(TreeNode *root) { vector<int> nodes; if(root == NULL) return nodes; TreeNode *temp = root; stack<TreeNode *> s; while(temp || !s.empty()) { while(temp) { s.push(temp); temp = temp->left; }// 左子树完毕 temp = s.top(); nodes.push_back(temp->val); s.pop(); temp = temp->right; } return nodes; }
vector<int> PostOrderTraverse2(TreeNode *root) { vector<int> nodes; vector<int> temp; if(root == NULL) return nodes; temp = PostOrderTraverse2(root->left); for(vector<int>::size_type i = 0 ; i != temp.size() ; ++i) nodes.push_back(temp[i]); temp = PostOrderTraverse2(root->right); for(vector<int>::size_type i = 0 ; i != temp.size() ; ++i) nodes.push_back(temp[i]); nodes.push_back(root->val); return nodes; }
PS:遇到根节点root,分两种情况讨论,如果根节点的右子树还没被访问,那么根节点入栈;否则输出根节点。
vector<int> PostOrderTraverse(TreeNode *root) { vector<int> nodes; if(root == NULL) return nodes; TreeNode *temp = root; TreeNode *pre = root; //记录前一次访问的节点 stack<TreeNode *> s; while(temp || !s.empty()) { while(temp) { s.push(temp); temp = temp->left; } temp = s.top(); if (temp->right == NULL || pre == temp->right) { nodes.push_back(temp->val); pre = temp; s.pop(); temp = NULL;//保证不重复访问 } else { temp = temp->right; } } return nodes; }
后记:上述3种算法的空间复杂度均为O(n)。
完整的代码为:
#include<iostream> #include<vector> #include<stack> using namespace std; struct TreeNode{ int val; TreeNode *left; TreeNode *right; TreeNode(int x):val(x),left(NULL),right(NULL){} }; vector<int> InOrderTraverse2(TreeNode *root) { vector<int> nodes; vector<int> temp; if(root == NULL) return nodes; temp = InOrderTraverse2(root->left); for(vector<int>::size_type i = 0 ; i != temp.size() ; ++i) nodes.push_back(temp[i]); nodes.push_back(root->val); temp = InOrderTraverse2(root->right); for(vector<int>::size_type i = 0 ; i != temp.size() ; ++i) nodes.push_back(temp[i]); return nodes; } vector<int> PreOrderTraverse2(TreeNode *root) { vector<int> nodes; vector<int> temp; if(root == NULL) return nodes; nodes.push_back(root->val); temp = PreOrderTraverse2(root->left); for(vector<int>::size_type i = 0 ; i != temp.size() ; ++i) nodes.push_back(temp[i]); temp = PreOrderTraverse2(root->right); for(vector<int>::size_type i = 0 ; i != temp.size() ; ++i) nodes.push_back(temp[i]); return nodes; } vector<int> PostOrderTraverse2(TreeNode *root) { vector<int> nodes; vector<int> temp; if(root == NULL) return nodes; temp = PostOrderTraverse2(root->left); for(vector<int>::size_type i = 0 ; i != temp.size() ; ++i) nodes.push_back(temp[i]); temp = PostOrderTraverse2(root->right); for(vector<int>::size_type i = 0 ; i != temp.size() ; ++i) nodes.push_back(temp[i]); nodes.push_back(root->val); return nodes; } vector<int> PreOrderTraverse(TreeNode *root) { vector<int> nodes; stack<TreeNode *> s; if(root == NULL) return nodes; TreeNode *temp = root; while(temp || !s.empty()) { while(temp) { s.push(temp);//入栈之前就访问 nodes.push_back(temp->val); temp = temp->left; } temp = s.top(); s.pop(); temp = temp->right; } return nodes; } vector<int> InOrderTraverse(TreeNode *root) { vector<int> nodes; if(root == NULL) return nodes; TreeNode *temp = root; stack<TreeNode *> s; while(temp || !s.empty()) { while(temp) { s.push(temp); temp = temp->left; } temp = s.top(); nodes.push_back(temp->val); s.pop(); temp = temp->right; } return nodes; } vector<int> PostOrderTraverse(TreeNode *root) { vector<int> nodes; if(root == NULL) return nodes; TreeNode *temp = root; TreeNode *pre = root; //记录前一次访问的节点 stack<TreeNode *> s; while(temp || !s.empty()) { while(temp) { s.push(temp); temp = temp->left; } temp = s.top(); if (temp->right == NULL || pre == temp->right) { nodes.push_back(temp->val); pre = temp; s.pop(); temp = NULL;//保证不重复访问 } else { temp = temp->right; } } return nodes; } int main() { vector<int> nodes; TreeNode *root = new TreeNode(1); TreeNode *node2 = new TreeNode(2); TreeNode *node3 = new TreeNode(3); TreeNode *node4 = new TreeNode(4); TreeNode *node5 = new TreeNode(5); root->left = node2; root->right = node3; node5->right = node4; node3->left = node5; cout << "InOrder recursively..." << endl; nodes = InOrderTraverse2(root); for(vector<int>::size_type i = 0; i != nodes.size(); i++) cout << nodes[i] << " "; cout << endl; cout << "InOrder iterativelly..." << endl; nodes = InOrderTraverse(root); for(vector<int>::size_type i = 0; i != nodes.size(); i++) cout << nodes[i] << " "; cout << endl; cout << "PreOrder recursively..." << endl; nodes = PreOrderTraverse2(root); for(vector<int>::size_type i = 0; i != nodes.size(); i++) cout << nodes[i] << " "; cout << endl; cout << "PreOrder iterativelly..." << endl; nodes = PreOrderTraverse(root); for(vector<int>::size_type i = 0; i != nodes.size(); i++) cout << nodes[i] << " "; cout << endl; cout << "PostOrder recursively..." << endl; nodes = PostOrderTraverse2(root); for(vector<int>::size_type i = 0; i != nodes.size(); i++) cout << nodes[i] << " "; cout << endl; cout << "PostOrder iterativelly..." << endl; nodes = PostOrderTraverse(root); for(vector<int>::size_type i = 0; i != nodes.size(); i++) cout << nodes[i] << " "; cout << endl; }
原文:http://blog.csdn.net/xuqingict/article/details/19089727