二叉树的遍历是二叉树的众多算法的基础。主要有,前序,中序与后序。
对于以下二叉树:
前序: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