二叉树的基本功能实现

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树的基本功能实现相关的知识,希望对你有一定的参考价值。

二叉树的创建、非递归与递归前中后遍历、层次遍历、求节点数目、深度、叶子节点个数、查找某一节点

#include<iostream>
#include<queue>
#include<stack>
using namespace std;
template<class T>
struct BinaryTreeNode
{
	BinaryTreeNode(const T&x)
		:_data(x)
		,_left(NULL)
		,_right(NULL)
	{}
	T _data;
	BinaryTreeNode<T>* _left;
	BinaryTreeNode<T>* _right;
};
template<class T>
class BinaryTree
{
public:
	BinaryTree()
		:_root(NULL)
	{}
	BinaryTree(T* a,size_t size)
	{	
		size_t index=0;
		_root=_CreateTree(a,index,size);
	}
	~BinaryTree()
	{
		_Destory(_root);
	}
	void PrevOrder()
	{
		_PrevOrder(_root);
		cout<<endl;
	}
	void InOrder()
	{
		_InOrder(_root);
		cout<<endl;
	}
	void PostOrder()
	{
		_PostOrder(_root);
		cout<<endl;
	}
	//层次遍历---常温故//采用队,压根,访问根,删根,压左右孩子
	void LevelOrder()
	{
		queue<BinaryTreeNode<T>*> q;
		if(_root!=NULL)
			q.push(_root);
		while(!q.empty())
		{
			BinaryTreeNode<T>* front=q.front();
			cout<<front->_data<<" ";
			q.pop();
			if(front->_left!=NULL)//易忘
				q.push(front->_left);
			if(front->_right!=NULL)
				q.push(front->_right);
		}
		cout<<endl;
	}
	//先序非递归遍历----->利用栈,先压根,访问根,删根,再分别压右孩子和左孩子,访问左右孩子,删左右孩子
	void PrevOrder_Non_R()
	{
		stack<BinaryTreeNode<T>*> s;
		if(_root!=NULL)
			s.push(_root);
		while(!s.empty())
		{
			BinaryTreeNode<T>* top=s.top();
			cout<<top->_data<<" ";
			s.pop();
			if(top->_right!=NULL)//top不是删去了吗,此时的top为空,还可以用top->_right???
				s.push(top->_right);
			if(top->_left!=NULL)
				s.push(top->_left);
		}
		cout<<endl;
	}
	//中序非递归遍历-------->一直压左,取栈顶,前序遍历top节点(再访问最左(栈顶)的节点,删左,把当前节点的右节点作为新根cur,重复前面的一直压左)
	//所有的右的访问是通过子树的cur
	//每个节点作为子树的跟被输出
	void InOrder_Non_R()
	{
		stack<BinaryTreeNode<T>*> s;
		BinaryTreeNode<T>* cur=_root;
		while(cur||!s.empty())//易忘------>每次都要判断cur是否为NULL
		{
			while(cur!=NULL)
			{
				s.push(cur);
				cur=cur->_left;
			}
			BinaryTreeNode<T>* top=s.top();
			cout<<top->_data<<" ";
			s.pop();
			cur=top->_right;
		}
		cout<<endl;
	}
	//后序遍历非递归--------->一直压左,访问最左,删左,把右孩子作为新根cur,一直压左,重复。。。
	//关键是判断当根节点没有左右节点时,是真的没有,还是刚刚左右孩子被删了,即右孩子是进过栈还是即将进,所有引入了另一个指针标记
	void PostOrder_Non_R()
	{
		stack<BinaryTreeNode<T>*> s;
		BinaryTreeNode<T>* cur=_root;
		BinaryTreeNode<T>* PrevVisited=NULL;
		while(cur||!s.empty())
		{
			while(cur!=NULL)
			{
				s.push(cur);
				cur=cur->_left;
			}
			//已访
			if(!s.empty())
			{
				BinaryTreeNode<T>* top=s.top();
				//右子树已访
				if(top->_right==NULL||top->_right==PrevVisited)
				{
					cout<<top->_data<<" ";
					s.pop();
					PrevVisited=top;
					//cur=top->_right;
				}
				///右子树未访,把当前右孩子作为新根重复一直压左遍历
				else
				{
					cur=top->_right;
				}
			}
		}
		cout<<endl;	
	}
	void Find(const T& x)
	{
		BinaryTreeNode<T>* Ret=_Find(_root,x);
		if(Ret)
			cout<<Ret->_data<<endl;
		else
			cout<<"所找数据不存在"<<endl;
	}
	void Size()
	{
		cout<<"Size:"<<_Size(_root)<<endl;
	}
	void Hight()
	{
		cout<<"Hight:"<<_Hight(_root)<<endl;
	}
	void LeafNum()
	{
		cout<<"LeafNum:"<<_LeafNum(_root)<<endl;
	}
protected:
	BinaryTreeNode<T>* _root;
	BinaryTreeNode<T>* _CreateTree(T* _array,size_t &index,size_t size)
	{	
		if(index<size)
		{
			if(_array[index]!=‘#‘)
			{
				BinaryTreeNode<T>* root=new BinaryTreeNode<T>(_array[index++]);
				root->_left=_CreateTree(_array,index,size);
				root->_right=_CreateTree(_array,index,size);
				return root;
			}
			else
			{
				index++;
				return NULL;
			}
		}
		return NULL;//为什么不可以删除
	}
	void _Destory(BinaryTreeNode<T>* &root)
	{
		if(root==NULL)
			return;
		if(root->_left==NULL&&root->_right==NULL)
		{
			delete root;
			root=NULL;//注意
			return;
		}
		_Destory(root->_left);
		_Destory(root->_right);
		delete root;		
	}
	void _PrevOrder(BinaryTreeNode<T>* &root)
	{
		if(root==NULL)
			return;
		cout<<root->_data;
		_PrevOrder(root->_left);
	    _PrevOrder(root->_right);
		
	}
	void _InOrder(BinaryTreeNode<T>* &root)
	{
		if(root==NULL)
			return;
		_InOrder(root->_left);
		cout<<root->_data;
		_InOrder(root->_right);
	}
	void _PostOrder(BinaryTreeNode<T>* &root)
	{
		if(root==NULL)
			return;
		_PostOrder(root->_left);
		_PostOrder(root->_right);
		cout<<root->_data;
	}
	BinaryTreeNode<T>* _Find(BinaryTreeNode<T>* root,const T& x)
	{
		if(root==NULL)
			return NULL;
		if(root->_data==x)
			return root;
		BinaryTreeNode<T>* lRet=_Find(root->_left,x);
		if(lRet)
			return lRet;
		return _Find(root->_right ,x);
			
		
	}
	int _Size(BinaryTreeNode<T>* &root)
	{
		if(root==NULL)
			return 0;
		return _Size(root->_left)+_Size(root->_right)+1;
	}
	int _Hight(BinaryTreeNode<T>* root)
	{
		if(root==NULL)
			return 0;
		int leftHight=_Hight(root->_left)+1;
		int rightHight=_Hight(root->_right)+1;
		return leftHight>rightHight?leftHight:rightHight;
	}
	int _LeafNum(BinaryTreeNode<T>* root)
	{
		if(root==NULL)
			return 0;
		if((root->_left==NULL)&&(root->_right==NULL))
		{
			return 1;
		}
		return _LeafNum(root->_left)+_LeafNum(root->_right);
	}
};
void Test1()
{
	
	char array[10]={‘a‘,‘b‘,‘d‘,‘#‘,‘#‘,‘e‘,‘#‘,‘#‘,‘c‘,‘f‘};
	BinaryTree<char> bt1(array,10);
	bt1.PrevOrder();
	bt1.PrevOrder_Non_R();
	bt1.InOrder();
	bt1.InOrder_Non_R();
	bt1.PostOrder();
	bt1.PostOrder_Non_R();
	bt1.Find(‘d‘);
	bt1.Find(‘z‘);
	bt1.LevelOrder();
	bt1.Size();
	bt1.Hight();
	bt1.LeafNum();
}
int main()
{
	Test1();
	system("pause");
	return 0;
}


本文出自 “sunshine225” 博客,请务必保留此出处http://10707460.blog.51cto.com/10697460/1757510

以上是关于二叉树的基本功能实现的主要内容,如果未能解决你的问题,请参考以下文章

C语言 二叉树与堆

C语言 二叉树与堆

C语言 二叉树与堆

编写一个程序,实现二叉树的各种基本运算

二叉树的实现及基本操作

数据结构 二叉树的简单理解和代码实现