春节快要到了,闲来无事,写写代码,在这篇博客中,主要针对二叉树的遍历,我实现了以下内容:
- 二叉树先序的递归遍历代码
- 二叉树先序的非递归遍历代码
- 二叉树中序的递归遍历代码
- 二叉树中序的非递归遍历代码
- 二叉树后序的递归遍历代码
- 二叉树后序的非递归遍历代码-
其中,因为后序实现的思路比较复杂,我借鉴博客:http://www.cnblogs.com/dolphin0520/archive/2011/08/25/2153720.html 的思路,讲解的很好,十分清楚。
二叉树的遍历实际上就是不停地入栈与出栈,关键在于搞清楚其入与出的先后次序。
以下,将具体的实现代码贴上来:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cassert>
#include <vector>
#include <stack>
using namespace std;
struct BinaryTree
{
int val;
BinaryTree * left;
BinaryTree * right;
BinaryTree(int val):val(val),left(NULL),right(NULL){}
}; //二叉树的结构定义
struct AccessTree
{
BinaryTree *tree;
int AccessTimes;
AccessTree():tree(NULL),AccessTimes(0){}
}; //这个结构主要是在后序的非递归遍历时使用的,其中的AccessTimes主要是来记录,当前节点出现在栈顶的次数的。因为后序遍历在操作时,需要判断当前节点是否应该出栈,而AccessTimes则是其标记。
void preOrderTraverse(BinaryTree * root); //递归实现
void preOrderTraverse2(BinaryTree * root);
void inOrderTraverse(BinaryTree * root);//递归实现
void inOrderTraverse2(BinaryTree * root);
void postOrderTraverse(BinaryTree * root);//递归实现
void postOrderTraverse2(BinaryTree * root); //方法一
void postOrderTraverse3(BinaryTree * root); //方法二
int main() //测试
{
BinaryTree *node1 = new BinaryTree(1);
BinaryTree *node2 = new BinaryTree(2);
BinaryTree *node3 = new BinaryTree(3);
BinaryTree *node4 = new BinaryTree(4);
BinaryTree *node5 = new BinaryTree(5);
BinaryTree *node6 = new BinaryTree(6);
BinaryTree *node7 = new BinaryTree(7);
BinaryTree *node8 = new BinaryTree(8);
node1 -> left = node2;
node1 -> right = node3;
node2 -> left = node4;
node2 -> right = node5;
node3 -> left = node6;
node3 -> right = node7;
node4 -> left = node8;
cout<< "pre 1 : " ;
preOrderTraverse(node1);
cout << endl;
cout<< "pre 2 : " ;
preOrderTraverse2(node1);
cout << endl;
cout<< "In 1 : " ;
inOrderTraverse(node1);
cout << endl;
cout<< "In 2 : " ;
inOrderTraverse2(node1);
cout << endl;
cout<< "post 1 : " ;
postOrderTraverse(node1);
cout << endl;
cout<< "post 2 : " ;
postOrderTraverse2(node1);
cout << endl;
cout<< "post 3 : " ;
postOrderTraverse3(node1);
cout << endl;
system("pause");
}
void preOrderTraverse(BinaryTree * root)
{
if(root != NULL)
{
cout << root -> val << " -> ";
preOrderTraverse(root -> left);
preOrderTraverse(root -> right);
}
}
void preOrderTraverse2(BinaryTree * root)
{
if(root != NULL)
{
stack <BinaryTree *> Btree_stack;
BinaryTree *p = root;
while( !Btree_stack.empty() || (p != NULL) )
{
while(p != NULL)
{
Btree_stack.push(p);
cout << p -> val << " -> ";
p = p -> left;
}
if(!Btree_stack.empty())
{
p = Btree_stack.top();
Btree_stack.pop();
p = p -> right;
}
}
}
}
void inOrderTraverse(BinaryTree * root)
{
if(root != NULL)
{
inOrderTraverse(root -> left);
cout << root -> val << " -> ";
inOrderTraverse(root -> right);
}
}
void inOrderTraverse2(BinaryTree * root)
{
if(root != NULL)
{
stack <BinaryTree *> Btree_stack;
BinaryTree *p = root;
while((p != NULL) || (!Btree_stack.empty()) )
{
while(p != NULL)
{
Btree_stack.push(p);
p = p -> left;
}
if(!Btree_stack.empty())
{
p = Btree_stack.top();
Btree_stack.pop();
cout << p -> val << " -> ";
p = p -> right;
}
}
}
}
void postOrderTraverse(BinaryTree * root)
{
if(root != NULL)
{
postOrderTraverse(root -> left);
postOrderTraverse(root -> right);
cout << root -> val << " -> ";
}
}
void postOrderTraverse2(BinaryTree * root)
{
if(root != NULL)
{
BinaryTree *p = root;
stack <AccessTree *> Btree_Acess_stack;
AccessTree *q;
while((p != NULL) || (!Btree_Acess_stack.empty()) )
{
while(p != NULL)
{
AccessTree * aTtree = new AccessTree();
aTtree -> tree = p;
aTtree -> AccessTimes++;
Btree_Acess_stack.push(aTtree);
p = p -> left;
}
if(!Btree_Acess_stack.empty())
{
q = Btree_Acess_stack.top();
if(q -> AccessTimes == 1)
{
p = q -> tree;
p = p -> right;
q -> AccessTimes++;
}
else if(q -> AccessTimes == 2)
{
p = q -> tree ;
cout << p -> val << " -> ";
Btree_Acess_stack.pop();
p = NULL;
}
}
}
}
}
void postOrderTraverse3(BinaryTree * root)
{
if(root != NULL)
{
stack <BinaryTree *> Btree_stack;
BinaryTree *p = root;
Btree_stack.push(p);
BinaryTree *recentlyAccess = NULL;
while((p != NULL) || (!Btree_stack.empty()))
{
while(((p != NULL) && (p -> left == NULL) && (p -> right == NULL)) ||( (p != NULL) && ( (recentlyAccess == p -> left) || (recentlyAccess == p -> right) )))
{
cout << p -> val << " -> ";
recentlyAccess = p;
// cout << endl <<"Btree_stack.size() :" << Btree_stack.size()<<endl;
Btree_stack.pop();
if(!Btree_stack.empty())
p = Btree_stack.top();
else
{
p = NULL;
break;
}
}
if(p != NULL)
{
if(p -> right != NULL)
{
// cout<<"push right: "<<p->right->val<<endl;
Btree_stack.push(p -> right);
recentlyAccess = p -> right;
}
if(p -> left != NULL)
{
// cout<<"push left: "<<p->left->val<<endl;
Btree_stack.push(p -> left);
recentlyAccess = p -> left;
}
}
if(!Btree_stack.empty())
{
p = Btree_stack.top();
recentlyAccess = p;
}
else
{
//cout << "Both empty!" << endl;
p = NULL;
}
}
}
}