二叉树的递归、迭代遍历的模板代码

#include <iostream>
#include <stack>
#include <queue>

using namespace std;

#define IsRoot(x)	(!(x->parent))
#define IsLChild(x) (!IsRoot(x) && (x == x->parent->lChild))
#define IsRChild(x) (!IsRoot(x) && (x == x->parent->rChild))

template <typename DataType>
class BinNode
{
	public:
		DataType data;
		BinNode *lChild,*rChild,*parent;
		BinNode():lChild(NULL),rChild(NULL),parent(NULL){};
		BinNode<DataType> * succ();


};

template <typename DataType>
BinNode<DataType> * BinNode<DataType>::succ()
{
	BinNode<DataType> *node = this;
	if(node->rChild)
	{   
		node = node->rChild;
		while(node->lChild)  
		{
			node = node->lChild;
		}

	}else
	{
		while(IsRChild(node)) node = node->parent;

		node = node->parent;
	}


	return node;



}

template <typename DataType>
class BinTree
{
	public:
		BinTree() {root = Create();}
		BinTree(DataType a[],int n);
		~BinTree() {Release(root);}
		void preorder_traversal(BinNode<DataType> *binNode);        //递归的方式进行前序的遍历
		void inorder_traversal(BinNode<DataType> *binNode);			//递归的方式进行中序的遍历
		void postorder_traversal(BinNode<DataType> *binNode);		//递归的方式进行后序的遍历
		void levelorder_traversal(BinNode<DataType> *binNode);		//层次遍历

		void iterative_preorder_traversal(BinNode<DataType> *binNode);  //迭代的方式进行前序的遍历版本一
		void iterative_preorder_traversal_2(BinNode<DataType> *binNode);	//迭代的方式进行前序的遍历版本二
		void iterative_inorder_traversal(BinNode<DataType> *binNode);	//迭代的方式进行中序的遍历版本一
		void iterative_inorder_traversal_2(BinNode<DataType> *binNode);	//迭代的方式进行中序的遍历版本二
		void iterative_inorder_traversal_3(BinNode<DataType> *binNode);	//迭代的方式进行中序的遍历版本三
		void iterative_postorder_traversal(BinNode<DataType> *binNode); //迭代的方式进行后序的遍历
		BinNode<DataType>*  getTheRoot();

	private:
		BinNode<DataType> *root;
		BinNode<DataType> * Create();
		void Release(BinNode<DataType> *binNode);
		static void VisitAlongLeftBranch(BinNode<DataType> *binNode,stack<BinNode<DataType>* >* s);        //static成员函数只能访问static成员,不能访问非static成员
		static void GoAlongLeftBranch(BinNode<DataType> *binNode, stack<BinNode<DataType>* > *s);
		static void GotoLeft(stack<BinNode<DataType>* > *s);

};

template <typename DataType>
BinNode<DataType>* BinTree<DataType>::Create()	//按照先序遍历方式创造二叉树
{
	DataType data;
	BinNode<DataType> *binNode = NULL;
	cout<<"please intput data:"<<endl;
	cin>>data;
	if(data == -1)
	{
		binNode = NULL;
		return binNode;
	}
	else 
	{
		binNode = new BinNode<DataType>();
		binNode->data = data;
		binNode->lChild = Create();		 //已经在BinTree<DataType>作用域中,所以不需要再声明在哪个作用域
		binNode->rChild = Create();
		if(binNode->lChild)
			binNode->lChild->parent = binNode;
		if(binNode->rChild)
			binNode->rChild->parent = binNode;
	}
	
	binNode->parent = NULL;			//根节点的parent为NULL
	return binNode;					//返回根节点
	
}

template <typename DataType>
BinTree<DataType>::BinTree(DataType a[],int len):root(NULL)  //按照层次遍历的方式用数组a构造二叉树
{
	BinNode<DataType> *binRoot ,*binLeft ,*binRight;
	int i = 0;
	queue<BinNode<DataType>*> que;
	root = new BinNode<DataType>();
	root->data = a[0];
	root->parent = NULL;
	que.push(root);
	while(!que.empty() && ++i < len)
	{
		binRoot = que.front();
		que.pop();

		binLeft = new BinNode<DataType>();
		binLeft->data = a[i];
		binRoot->lChild = binLeft;
		binLeft->parent = binRoot;
		que.push(binLeft);
		i++;
        
		if(i >= len) break;
		binRight = new BinNode<DataType>();
		binRight->data = a[i];
		binRoot->rChild = binRight;
		binRight->parent = binRoot;
		que.push(binRight);
		

	}
}

template <typename DataType>
void BinTree<DataType>::Release(BinNode<DataType> *binNode)		//按照后递归将二叉树释放掉
{
	if(binNode)
	{
		Release(binNode->lChild);
		Release(binNode->rChild);
		delete(binNode);
	}
}

template <typename DataType>
void BinTree<DataType>::preorder_traversal(BinNode<DataType> *binNode)     //先序递归二叉树
{
	if(binNode != NULL)
	{
		cout<<binNode->data<<'\t';
		preorder_traversal(binNode->lChild);
		preorder_traversal(binNode->rChild);

	}
}

template <typename DataType>
void BinTree<DataType>::inorder_traversal(BinNode<DataType> *binNode)     //中序递归二叉树
{
	if(binNode->lChild != NULL)
		inorder_traversal(binNode->lChild);
	cout<<binNode->data<<'/t';
	if(binNode->rChild != NULL)
		inorder_traversal(binNode->rChild);

}

template <typename DataType>
void BinTree<DataType>::postorder_traversal(BinNode<DataType> * binNode)	//后序递归二叉树
{
	if(binNode->lChild != NULL)
		postorder_traversal(binNode->lChild);
	if(binNode->rChild != NULL)
		postorder_traversal(binNode->rChild);
	cout<<binNode->data<<'/t';
}


template <typename DataType>
void BinTree<DataType>::iterative_preorder_traversal(BinNode<DataType> *binNode)  //先序迭代二叉树版本一
{
	stack< BinNode<DataType> * > *s = new stack< BinNode<DataType> *>();
	if(binNode) 
		s->push(binNode);
	while(!s->empty())
	{
		binNode = s.pop();
		cout<<binNode->data<<'\t';
		if(binNode->rChild)
			s.push(binNode->rChild);
		if(binNode->lChild)
			s.push(binNode->lChild);

	}

	release(s);      //动态分配的变量,要记得自己手动释放
} 


template <typename DataType>
 void BinTree<DataType>::VisitAlongLeftBranch(BinNode<DataType> *binNode,  stack< BinNode<DataType>* >* s)
{
	while(binNode)
	{
		cout<<binNode->data<<'\t';
		if(binNode->rChild)
			s->push(binNode->rChild);
		binNode = binNode->lChild;
			
	}
}
template <typename DataType>
void BinTree<DataType>::iterative_preorder_traversal_2(BinNode<DataType> *binNode)     //先序迭代遍历二叉树版本二
{  
	 
	stack< BinNode<DataType> * > *s = new stack< BinNode<DataType> * >();
	while(true)
	{
		BinTree<DataType>::VisitAlongLeftBranch(binNode, s);
		if(s->empty()) 
			break;
		binNode = s->top();
		s->pop();
	}
}


template <typename DataType>
 void  BinTree<DataType>::GoAlongLeftBranch(BinNode<DataType> *binNode, stack< BinNode<DataType>* > *s)
{
	while(binNode)
	{
		s->push(binNode);
		binNode = binNode->lChild;
	}
}
template <typename DataType>
void BinTree<DataType>::iterative_inorder_traversal(BinNode<DataType> *binNode)     //中序迭代遍历二叉树版本一
{
	stack< BinNode<DataType>* > *s = new stack< BinNode<DataType>* >();
	while(true)
	{
		BinTree<DataType>::GoAlongLeftBranch(binNode,s);
		if(s->empty()) 
			break;
		binNode = s->top();
		s->pop();
		cout<<binNode->data<<'\t';
		binNode = binNode->rChild;
	}

	delete(s);	//释放栈
}

template <typename DataType>
void BinTree<DataType>::iterative_inorder_traversal_2(BinNode<DataType> *binNode)			//中序迭代遍历二叉树版本二
{
	stack< BinNode<DataType>* > *s = new stack< BinNode<DataType>* >();
	while(true)
	{
		if(binNode)
		{	
			s->push(binNode);
			binNode = binNode->lChild;
		}else if(!s->empty())
			{
			binNode = s->top();
			s->pop();
			cout<<binNode->data<<'\t';
			binNode = binNode->rChild;
		}else
			{
			delete(s); 
			break;
		}
	}
}

template <typename DataType>
void BinTree<DataType>::iterative_inorder_traversal_3(BinNode<DataType> *binNode)  //中序迭代遍历二叉树
{
	bool backtrack = false;
	while(true)
	{
		if(!backtrack && binNode->lChild)
			binNode = binNode->lChild;
		else
		{
			cout<<binNode->data<<'\t';
			if(binNode->rChild)
			{
				binNode = binNode->rChild;
				backtrack = false;
			}else
			{
				if(!(binNode = binNode->succ()))	break;
				backtrack = true; 
														
			}
		}
	}
}

template <typename DataType>
void BinTree<DataType>::GotoLeft(stack<BinNode<DataType>*> *s)
{
	BinNode<DataType> *node;
	while(node = s->top())
	{
		if(node->lChild)					//尽可能的向左
		{
			if(node->rChild)
				s->push(node->rChild);
			s->push(node->lChild);
		}else
		{
			s->push(node->rChild);
		}

		
	}

	s->pop();			//返回之前,弹出栈顶的空节点
}
template <typename DataType>
void BinTree<DataType>::iterative_postorder_traversal(BinNode<DataType> *binNode)	//后序迭代遍历二叉树
{
	BinNode<DataType> *top;
	stack<BinNode<DataType> *> *s = new stack<BinNode<DataType> *>();
	if(binNode)
		s->push(binNode);
	while(!s->empty())
	{	
		top = s->top();
		if(top != binNode->parent)				//如果不是其父亲节点,则肯定是其右兄弟。   
			GotoLeft(s)	;			//在以其右兄弟为根之树中进行递归深入其中。
		binNode = s->top();
		cout<<binNode->data<<'\t';
		s->pop();

	}
}

template <typename DataType>
void BinTree<DataType>::levelorder_traversal(BinNode<DataType> *binNode)    //层次遍历
{
	queue<BinNode<DataType>*> que;
	que.push(binNode);
	while(!que.empty())
	{
		binNode = que.front();
		que.pop();
		cout<<binNode->data<<'\t';
		if(binNode->lChild)
			que.push(binNode->lChild);
		if(binNode->rChild)
			que.push(binNode->rChild);
	}
}

template <typename DataType>
BinNode<DataType>* BinTree<DataType>::getTheRoot()		//返回根节点
{
	return root;											//这里一开始我返回的是*root,导致后面使用栈的时候,如果用数组构造二叉树,那么在后序遍历中push的是形参的BinNode<DataType>的地址,所以这里用指针比较好。。。找了一个小时。。。。
}

void main()
{
	int a[10] = {1,2,3,4,5,6,7,8,9,10};
    BinTree<int> tree(a,10);
    cout<<"the source is: a[10] = {1,2,3,4,5,6,7,8,9,10}"<<endl;
	cout<<"the preorder_traversal is:"<<endl;
	BinNode<int>* root = tree.getTheRoot();
	tree.preorder_traversal(root);

	cout<<"the iterative_preorder_traversal_2 is:"<<endl;
	root = tree.getTheRoot();
	tree.iterative_preorder_traversal_2(root);

	cout<<"the iterative_inorder_traversal is:"<<endl;
    root = tree.getTheRoot();
	tree.iterative_inorder_traversal(root);

	cout<<"the iterative_inorder_traversal_2 is:"<<endl;
    root = tree.getTheRoot();
	tree.iterative_inorder_traversal_2(root);

	cout<<"the iterative_inorder_traversal_3 is:"<<endl;
	root = tree.getTheRoot();
	tree.iterative_inorder_traversal_3(root);

	cout<<"the iterative_postorder_traversal is:"<<endl;
    root = tree.getTheRoot();
	tree.iterative_postorder_traversal(root);

	cout<<"the levelorder_traversal is:"<<endl;
    root = tree.getTheRoot();
	tree.levelorder_traversal(root);

	cout<<"please input the source :"<<endl;
    BinTree<int> tree1;
	cout<<"the preorder_traversal is:"<<endl;
    root = tree1.getTheRoot();
	tree1.preorder_traversal(root);

	cout<<"the iterative_preorder_traversal_2 is:"<<endl;
	root = tree1.getTheRoot();
	tree1.iterative_preorder_traversal_2(root);

	cout<<"the iterative_inorder_traversal is:"<<endl;
    root = tree1.getTheRoot();
	tree1.iterative_inorder_traversal(root);

	cout<<"the iterative_inorder_traversal_2 is:"<<endl;
    root = tree1.getTheRoot();
	tree1.iterative_inorder_traversal_2(root);

	cout<<"the iterative_inorder_traversal_3 is:"<<endl;
	root = tree1.getTheRoot();
	tree1.iterative_inorder_traversal_3(root);

	cout<<"the iterative_postorder_traversal is:"<<endl;
    root = tree1.getTheRoot();
	tree1.iterative_postorder_traversal(root);

	cout<<"the levelorder_traversal is:"<<endl;
    root = tree1.getTheRoot();
	tree1.levelorder_traversal(root);




}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值