二叉树主要有三种遍历方式:前序遍历、中序遍历和后序遍历,每种方式都有递归和非递归两种方法。递归的方法简单明了,但是会比较耗时,非递归的方法效率相对较高,但是算法也比较晦涩。本文就这三种遍历方式做简单的介绍。
数据结构:
struct BTree{
        int data;
	BTree *lchild;
	BTree *rchild;
};一、 前序遍历
1. 递归的算法:
前序遍历每次先访问根结点,然后访问左子树,接着是右子树。用递归的方法很容易写出递归的算法:
void preTraverse(BTree *t)
{
	cout<<t->data<<" ";
	if(t->lchild)
		preTraverse(t->lchild);
	if(t->rchild)
		preTraverse(t->rchild);
}2. 非递归算法:
由于函数的递归调用归根到底使用的是栈保存相关的变量,我们可以按照递归调用的过程,借助于栈将递归的算法改成非递归的算法。
void preOrder(BTree *t)
{
	stack<BTree *> stk;
	stk.push(t);
	while(!stk.empty())
	{
		BTree *q = stk.top();
		stk.pop();
		cout<<q->data<<" ";
		if(q->rchild)
			stk.push(q->rchild);
		if(q->lchild)
			stk.push(q->lchild);
	}
	cout<<endl;
}  这里我们采用一个栈保存访问过的节点,先访问根节点,然后将右子树根节点入栈,接着是左子树根节点。之所以先右后左,因为栈是后进先出的数据结构,我们要先访问左子树后访问右子树,所以要先将右子树根节点入栈再将左子树根节点入栈。二、 中序遍历
1. 递归算法:
中序遍历先访问左子树,然后访问根节点,接着访问右子树。递归的算法如下:
void inTraverse(BTree *t)
{
	if(t->lchild)
		inTraverse(t->lchild);
	cout<<t->data<<" ";
	if(t->rchild)
		inTraverse(t->rchild);
}中序遍历的时候,先访问左子树,再访问根节点,接着是右子树,那么我们需要用栈保存未访问的节点。当节点的左子树已经被访问之后,就将节点出栈,进行访问,然后将右子树根节点入栈。
void inOrder(BTree *t)
{
	stack<BTree *> stk;
	BTree *p = t;
	while(!stk.empty() || p)
	{
		while(p)
		{
			stk.push(p);
			p = p->lchild;
		}
		p = stk.top();
		cout<<p->data<<" ";
		stk.pop();
		p = p->rchild;
	}
	cout<<endl;
}
三、 后序遍历
1. 递归算法:
后序遍历的时候先访问左子树,然后是右子树,最后才访问根节点。递归算法如下:
void postTraverse(BTree *t)
{
	if(t->lchild)
		postTraverse(t->lchild);
	if(t->rchild)
		postTraverse(t->rchild);
	cout<<t->data<<" ";
}
后序遍历的非递归算法较复杂,因为后续遍历需要确认左右子树都访问之后才访问根节点,因此,不仅需要栈保存节点,而且需要有状态指示其左子树和右子树都已经被访问过了,这个时候才可以访问根节点。
void postOrder(BTree *t)
{
	stack<BTree *> stk;
	vector<int> tag;
	int k = -1;
	BTree *p = t;
	while(!stk.empty() || p)
	{
		while(p)
		{
			stk.push(p);
			tag.push_back(1);
			++k;
			p = p->lchild;
		}
		while(!stk.empty() && tag.back() == 2){
			p = stk.top();
			cout<<p->data<<" ";
			stk.pop();
			tag.pop_back();
			--k;
		}
		if(stk.empty())
			break;
		p = stk.top();
		tag[k] = 2;
		p = p->rchild;
		
	}
	cout<<endl;
}
四、 层序遍历
二叉树的层序遍历有点类似于图的广度优先搜索算法,先访问根节点,接着将临近的每个节点都入队列,按照入队列/出队列的顺序访问每个元素。
//层序遍历---非递归---借助于队列
void levelOrder(BTree *t)
{
	queue<BTree *> Q;
	Q.push(t);
	while(!Q.empty())
	{
		BTree *q = Q.front();
		Q.pop();
		cout<<q->data<<" ";
		if(q->lchild)
			Q.push(q->lchild);
		if(q->rchild)
			Q.push(q->rchild);
	}
	cout<<endl;
}
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <stack>
#include <queue>
using namespace std;
struct BTree{
	int data;
	BTree *lchild;
	BTree *rchild;
	BTree(){
		this->data = 0;
		this->lchild = NULL;
		this->rchild = NULL;
	}
	BTree(int d){
		this->data = d;
		this->lchild = NULL;
		this->rchild = NULL;
	}
};
BTree* buildNode(int a[], int k);
void PrintTree(BTree *p);
void preTraverse(BTree *t);
void inTraverse(BTree *t);
void postTraverse(BTree *t);
void levelOrder(BTree *t);
void preOrder(BTree *t);
void inOrder(BTree *t);
void postOrder(BTree *t);
int main(int argc, char* argv[])
{
	int n;
	while(cin>>n)
	{
		int *a = new int[n+1];
		a[0] = n;
		for(int k = 1; k <= n; ++k)
			cin>>a[k];
		BTree *t = buildNode(a, 1);
		PrintTree(t);
		
		cout<<"**************levelOrder--non-recursive********"<<endl;
		levelOrder(t);
		cout<<"*************************************************"<<endl;
		cout<<"--------------preTraverse--recursive-------------"<<endl;
		preTraverse(t);
		cout<<endl<<"-------------------------------------------------"<<endl;
		cout<<"**************preOrder--non-recursive********"<<endl;
		preOrder(t);
		cout<<"*************************************************"<<endl;
		cout<<"--------------inTraverse--recursive-------------"<<endl;
		inTraverse(t);
		cout<<endl<<"-------------------------------------------------"<<endl;
		cout<<"**************inOrder--non-recursive********"<<endl;
		inOrder(t);
		cout<<"*************************************************"<<endl;
		cout<<"--------------postTraverse--recursive-------------"<<endl;
		postTraverse(t);
		cout<<endl<<"-------------------------------------------------"<<endl;
		cout<<"**************postOrder--non-recursive********"<<endl;
		postOrder(t);
		cout<<"*************************************************"<<endl;
	}
	
	return 0;
}
//后续遍历---非递归
void postOrder(BTree *t)
{
	stack<BTree *> stk;
	vector<int> tag;
	int k = -1;
	BTree *p = t;
	while(!stk.empty() || p)
	{
		while(p)
		{
			stk.push(p);
			tag.push_back(1);
			++k;
			p = p->lchild;
		}
		while(!stk.empty() && tag.back() == 2){
			p = stk.top();
			cout<<p->data<<" ";
			stk.pop();
			tag.pop_back();
			--k;
		}
		if(stk.empty())
			break;
		p = stk.top();
		tag[k] = 2;
		p = p->rchild;
		
	}
	cout<<endl;
}
//中序遍历---非递归
void inOrder(BTree *t)
{
	stack<BTree *> stk;
	BTree *p = t;
	while(!stk.empty() || p)
	{
		while(p)
		{
			stk.push(p);
			p = p->lchild;
		}
		p = stk.top();
		cout<<p->data<<" ";
		stk.pop();
		p = p->rchild;
	}
	cout<<endl;
}
//先序遍历---非递归----借助于栈
void preOrder(BTree *t)
{
	stack<BTree *> stk;
	stk.push(t);
	while(!stk.empty())
	{
		BTree *q = stk.top();
		stk.pop();
		cout<<q->data<<" ";
		if(q->rchild)
			stk.push(q->rchild);
		if(q->lchild)
			stk.push(q->lchild);
	}
	cout<<endl;
}
//层序遍历---非递归---借助于队列
void levelOrder(BTree *t)
{
	queue<BTree *> Q;
	Q.push(t);
	while(!Q.empty())
	{
		BTree *q = Q.front();
		Q.pop();
		cout<<q->data<<" ";
		if(q->lchild)
			Q.push(q->lchild);
		if(q->rchild)
			Q.push(q->rchild);
	}
	cout<<endl;
}
//后序遍历
void postTraverse(BTree *t)
{
	if(t->lchild)
		postTraverse(t->lchild);
	if(t->rchild)
		postTraverse(t->rchild);
	cout<<t->data<<" ";
}
//中序遍历
void inTraverse(BTree *t)
{
	if(t->lchild)
		inTraverse(t->lchild);
	cout<<t->data<<" ";
	if(t->rchild)
		inTraverse(t->rchild);
}
//pre-order
void preTraverse(BTree *t)
{
	cout<<t->data<<" ";
	if(t->lchild)
		preTraverse(t->lchild);
	if(t->rchild)
		preTraverse(t->rchild);
}
BTree* buildNode(int a[], int k){//构建第k个Node
	if(k > a[0] || a[k] == -1)
		return NULL;
	BTree *p = new BTree(a[k]);
	p->lchild = buildNode(a, 2*k);
	p->rchild = buildNode(a, 2*k+1);
	return p;
}
void PrintTree(BTree *p)
{
	int k = 1, cnt = 0;
	queue<BTree *> que;
	que.push(p);
	while(!que.empty())
	{
		BTree *q = que.front();
		que.pop();
		if(q->lchild != NULL)
			que.push(q->lchild);
		if(q->rchild != NULL)
			que.push(q->rchild);
		cout<<q->data<<" ";
		++cnt;
		if(cnt == k){
			cout<<endl;
			k = 2*k;
			cnt = 0;
		}
	}
	if(cnt != 0)
		cout<<endl;
}
原文:http://blog.csdn.net/uilotus/article/details/38332701