码迷,mamicode.com
首页 > 其他好文 > 详细

二叉树的建立、三种(递归、非递归)遍历方法

时间:2015-06-09 10:04:17      阅读:223      评论:0      收藏:0      [点我收藏+]

标签:

二叉树定义:

1.有且仅有一个特定的称之为根root的结点

2.当n>1时,除根结点之外的其余结点分为两个互不相交的子集。他们称为二叉树的左子树和右子树。

二叉树的一种建立方法:

若对有n个结点的完全二叉树进行顺序编号(1<=i<=n),那么,对于编号为i(i>=1)的结点。

当i=1时,该结点为根,它无双亲结点;

当i>1时,该节点的双亲编号为[i/2];

若2i<=n,该结点为编号为2i的左孩子,否则没有左孩子

当2i+1<=n,该结点有编号为2i+1的右孩子,否则没有右孩子

利用上个性质,对任意二叉树,先按满二叉树对其所有结点进行编号。

注意:由于此树并非完全树,所以结点的编号并不连续。

遍历二叉树:

遍历二叉树是指以一定的次序访问二叉树中的每个结点,并且每个结点仅被访问一次,访问结点是指进行各种操作的简称。3种遍历次序:中根遍历二叉树、先根遍历二叉树、后根遍历二叉树。

递归算法:

先根遍历:如果根不为空,1.访问根结点2.按先根次序遍历左子树,3.按先根次序遍历右子树,否则返回。

中根遍历:如果根不为空,1.按中根次序遍历左子树,2.访问根结点,3.按中根次序遍历右子树,否则返回。

后根遍历:如果根不为空,1.按后根次序遍历左子树,2.按后根次序遍历右子树,3.访问根结点,否则返回。

中根遍历非递归算法:

需要人为设置一个栈来存放所经过的根结点的指针(栈我图简单,直接调用STL标准库的),第一次遇到根结点并不访问,而是如栈,然后中根遍历左子树。左子树遍历结束后,第二次遇到根结点,退栈并访问该结点。然后遍历右子树。

先根遍历非递归算法:同中根遍历非递归算法,只是把输出位置提前

后根遍历非递归算法:

后根遍历在搜索线第一次经过根结点时不访问进行如栈,在遍历左子树之后,搜索线第二次经过根结点时也不能访问,继续遍历右子树,直到搜索线第三次经过根结点时,退栈并且访问根结点。因此,另设一个辅助栈用来记录经过某个结点的次数。

废话少说,上代码......

BinaryTree.h

#ifndef BINARYTREE_H_
#define BINARYTREE_H_
typedef int T;
struct Node
{
	T data;
	Node *lch;
	Node *rch;
};
class BinaryTree
{
protected:
	Node *root;
public:
	BinaryTree();
	~BinaryTree();
	void Create();
	void preorder();
	void Preorder()
	{
		Preorder(root);
	}
	void inorder();
	void Inorder()
	{
		Inorder(root);
	}
	void postorder();
	void Postorder()
	{
		Postorder(root);
	}
private:
	void Inorder(Node *p);
	void Preorder(Node *p);
	void Postorder(Node *p);
	void Destroy(Node *p);
};

#endif
BinaryTree.cpp

#include "BinaryTree.h"
#include <iostream>
#include <stack>
using namespace std;
BinaryTree::BinaryTree()
{
	root=NULL;
}
BinaryTree::~BinaryTree()
{
	Destroy(root);
	root=NULL;
}
void BinaryTree::Inorder(Node *p)
{
	if(p!=NULL)
	{
		Inorder(p->lch);
		cout<<p->data<<" ";
		Inorder(p->rch);
	}
}
//非递归法实现中根遍历
void BinaryTree::inorder()
{
	Node *p=root;
	Node *q;
	stack<Node *> S;
	do
	{
		while(p!=NULL)
		{
			S.push(p);
			p=p->lch;
		}
		p=S.top();
		S.pop();
		cout<<p->data<<" ";
		p=p->rch;	
	}while(!(S.empty() && p==NULL));
}
//先根遍历,用递归法
void BinaryTree::Preorder(Node *p)
{
	if(p!=NULL)
	{
		cout<<p->data<<" ";
		Preorder(p->lch);
		Preorder(p->rch);
	}
}
//先根遍历的非递归算法
void BinaryTree::preorder()
{
	Node *p=root;
	stack<Node *> S;
	do
	{
		while(p!=NULL)
		{
			S.push(p);
			cout<<p->data<<" ";
			p=p->lch;
		}
		p=S.top();
		p=p->rch;
		S.pop();
	}while(!(S.empty() && p==NULL));
}
//后根
void BinaryTree::Postorder(Node *p)
{
	if(p!=NULL)
	{
		Postorder(p->lch);
		Postorder(p->rch);
		cout<<p->data<<" ";	
	}
}
//非递归法实现后根遍历
void BinaryTree::postorder()
{
	stack<Node *>S;
	stack<int> s;
	Node *p=root;
	int t=0;
	do
	{
		while(p!=NULL)
		{
			s.push(1);
			S.push(p);
			p=p->lch;
		}
		t=s.top();
		if(t==2)
		{
			p=S.top();
			S.pop();
			s.pop();
			cout<<p->data<<" ";
			p=NULL;
		}
		if(!s.empty())
		{
			t=s.top();
		}
		if(t==1)
		{
			p=S.top();
			p=p->rch;
			s.pop();
			s.push(2);
		}
		
	}while(!(S.empty() && p==NULL));
}
void BinaryTree::Destroy(Node *p)
{
	if(p!=NULL)
	{
		Destroy(p->lch);
		Destroy(p->rch);
		delete p;
	}
}

void BinaryTree::Create()
{
	Node *q, *s[20]; T x; int i,j;
	cout<<"请按照二叉树的层序,自上而下自左至右的顺序组织数据"<<endl;
	cout<<"每次输入结点的序号和数据,假设根结点值为11;"<<endl;
	cout<<"那么输入应是:1 11,若两者都输入0,则输入结束。"<<endl;
	root=NULL;
	cout<<"i,x = "; cin>>i>>x;
	while((i!=0)&&(x!=0))
	{
		q=new Node;
		q->data=x;
		q->lch=NULL;
		q->rch=NULL;
		s[i]=q;
		if(i==1)
		{
			root=q;
		}
		else
		{
			j=i/2;
			if(i%2==0)
			{
				s[j]->lch=s[i];
			}
			else
			{
				s[j]->rch=s[i];
			}
		}
		cout<<"i,x = "; cin>>i>>x;
	}
	cout<<"二叉树建立完毕!"<<endl;
}
main.cpp

//直接调用STL库中的栈吧,不在
#include "BinaryTree.h"
#include <iostream>

using namespace std;

int main()
{
	/*cout<<"hello,world"<<endl;*/
	BinaryTree BT;
	BT.Create();
	cout<<"先根遍历二叉树:"<<endl;
	BT.Preorder();
	cout<<endl<<"先根非递归遍历二叉树:"<<endl;
	BT.preorder();
	cout<<endl<<"中根遍历二叉树:"<<endl;
	BT.Inorder();
	cout<<endl<<"中根非递归遍历二叉树:"<<endl;
	BT.inorder();
	cout<<endl<<"后根遍历二叉树:"<<endl;
	BT.Postorder();
	cout<<endl<<"后根非递归遍历二叉树:"<<endl;
	BT.postorder();
	cout<<endl;
	system("pause");
	return 0;
}
结果:
技术分享









二叉树的建立、三种(递归、非递归)遍历方法

标签:

原文地址:http://blog.csdn.net/jiang111_111shan/article/details/46418273

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!