template <class DT>
struct BTNode
{
	DT data ;		                			//数据域
	BTNode* lchild;								//指向左子树的指针
	BTNode* rchild;								//指向右子树的指针
};


//算法5.1										先序遍历递归算法
template <class DT>
void PreOrDerBiTree(BTNode<DT> *bt)
{
	if(bt!=NULL)
	{
		cout<<bt->data<<' ';	     			//输出结点上的数据
		PreOrDerBiTree(bt->lchild);				//递归的调用前序遍历左子树
		PreOrDerBiTree(bt->rchild);				//递归的调用前序遍历右子树
	}
	return;
}

//算法5.2										中序遍历递归算法
template <class DT>
void InOrDerBiTree(BTNode<DT> *bt)
{
	if(bt!=NULL)
	{
		InOrDerBiTree(bt->lchild);				//递归的调用中序遍历左子树
		cout<<bt->data<<' ';	     			//输出结点上的数据
		InOrDerBiTree(bt->rchild);  			//递归的调用中序遍历右子树
	}
	return;
}

//算法5.3										后序遍历递归算法
template <class DT>
void PostOrDerBiTree(BTNode<DT> *bt)
{
	if(bt!=NULL)
	{
		PostOrDerBiTree(bt->lchild);			//递归的调用后序遍历左子树
		PostOrDerBiTree(bt->rchild);			//递归的调用后序遍历右子树
		cout<<bt->data<<' ';					//输出结点上的数据
	}
	return;
}


//算法5.4										层序遍历算法	
template<class DT>
void LevelBiTree(BTNode<DT> *bt)
{
	SqQueue<DT> Q;								// 创建一个队
	int m=20;                          
	InitQueue(Q,m);
	BTNode<DT>* p;
	p=bt;                              
	if(p) EnQueue(Q,p);							// 树非空，入队              
	while (!QueueEmpty(Q))						// 队非空
	{
		DeQueue(Q,p);							// 出队
		cout<<p->data;							// 访问
		if(p->lchild!=NULL)						// 有左孩子
			EnQueue(Q, p->lchild);				// 左孩子入队
		if(p->rchild!=NULL)						// 有右孩子
			EnQueue(Q, p->rchild);				// 右孩子入队
	}
    DestroyQueue(Q);							// 销毁队列
}


//算法5.5										先序非遍历递归算法
template <class DT>
void PreOrderBiTree_N(BTNode<DT> *bt)
{
	SqStack<DT> S;								// 创建栈
	int m=20;
	InitStack(S, m);
    BTNode<DT>* p;
	p=bt;
	while (p!=NULL || !StackEmpty(S))			// 树非空或栈非空
	{
		while(p!=NULL)							// 结点非空
		{
			cout<<p->data<<' ';					// 访问结点
			Push(S,p);							// 入栈
			p=p->lchild;						// 转左子树
		}
		if(!StackEmpty(S))						// 栈非空
		{
			Pop(S,p);							// 出栈
		    p=p->rchild;						    // 转出栈结点的右子树
		}
	}
	DestroyStack(S);							//销毁栈
}


//算法5.6 中序非遍历递归算法
template <class DT>
void InOrderBiTree_N(BTNode<DT> *bt)
{
	SqStack<DT> S;								// 创建一个栈
	int m=20;
	InitStack(S, m);
    BTNode<DT>* p;
	p=bt;
	while (p!=NULL || !StackEmpty(S))			// 结点非空或栈非空
	{
		while(p!=NULL)							// 结点非空
		{
			Push(S,p);							// 出栈
			p=p->lchild;						// 转出栈结点右子树
		}
		if(!StackEmpty(S))						// 栈非空
		{
			Pop(S,p);							// 出栈
			cout<<p->data<<' ';					// 访问出栈结点
			p=p->rchild;						// 转出栈结点的右子树
		}
	}
	DestroyStack(S);							// 销毁栈
}



//算法5.7										后序非遍历递归算法
template <class DT>
void PostOrderBiTree_N(BTNode<DT> *bt)
{
	SqStack<DT> S;								// 创建一个栈
	int m=20;
	InitStack(S, m);
    BTNode<DT>* p;                        
	BTNode<DT>* r;
	p=bt;
	bool flag;                           
	do
	{
		while(p)								// 结点非空
		{
			Push(S,p);							// 结点入栈
			p=p->lchild;						// 转左子树
		}
		r=NULL;									// 指向刚被访问点，初值为空
        flag=true;								// true表示处理栈顶结点                     
		while(!StackEmpty(S) && flag)			// 栈非空且当前处理的是栈顶结点
		{
			GetTop(S,p);						// 获取栈顶元素
			if(p->rchild==r)					// 如果 当前结点是栈元素的右孩子
			{
				cout<<p->data<<' ';				// 访问栈顶元素
				Pop(S,p);						// 出栈
				r=p;							// r指向被访问结点
			}
			else								 // 否则
			{
				p=p->rchild;					// 转栈顶元素右孩子
				flag=false;						// 处理非栈顶结点
			}
		}
	}while(!StackEmpty(S));						// 栈非空，循环
	cout<<endl; 
	DestroyStack(S);							// 销毁栈
}


//算法5.8                                      创建二叉树
template <class DT>
void CreateBiTree(BTNode<DT> *&bt)
{	
	char ch;
	cin>>ch;				                    // 输入根结点的数据
	if(ch=='#')                                 // # 表示指针为空，说明树为空
		bt=NULL ;	
	else 
	{
		bt=new BTNode<DT>;	                    // 申请内存
	    if(!bt)
		{
			cout<<"申请内存失败！"<<endl;
		    exit(-1);                           // 申请内存失败退出
		}
	    bt->data=ch;
	   	CreateBiTree(bt->lchild);               // 创建根结点左子树
	    CreateBiTree(bt->rchild);               // 创建根结点右子树
	}
	return;
}


//算法5.9 销毁二叉树
template <class DT>
void DestroyBiTree(BTNode<DT> *&bt)
{
	if(bt)                                     // 树非空
	{
		DestroyBiTree(bt->lchild);             // 销毁左子树
		DestroyBiTree(bt->rchild);             // 销毁右子树
		delete bt;
	}
}


//算法5.10										结点查找

template<class DT>
BTNode<DT>* Search(BTNode<DT> * bt, DT e)		// 查找值为e的元素
{
	BTNode<DT> *p;
	if(bt==NULL)								// 结点为空，返回
		return NULL;
	else if(bt->data==e)						// 找到，返回结点指针
		return bt;
	else										// 结点值不为e       
	{
		p=Search(bt->lchild,e);					// 在左子树上查找
		if(p!=NULL)								// 找到
			return p;							// 返回结点指针
		else									// 未找到
			return Search(bt->rchild,e);		// 转右子树上查找
	}	
}

//算法5.11										求树深
template <class DT>
int Depth(BTNode<DT> *bt)
{
	int hl,hr;
	if(bt==NULL)								// 树空
		return 0;								// 深度为0
	else										// 树非空
	{
		
		hl=Depth(bt->lchild);					// 求左子树深度
		hr=Depth(bt->lchild);					// 求右子树深度
		if(hl>hr)								// 左子树高
			return hl+1;						// 树高为左子树高加1
		else return hr+1;						// 左子树高,树高为左子树高加1
	}
}


//算法5.12										结点计数
template <class DT>
int NodeCount(BTNode<DT> *bt)
{
	if(bt==NULL)								// 空树，结点数为0
		return 0;
	else										// 非空树，结点数为左、右子树结点数的和加1
		return NodeCount(bt->lchild)+NodeCount(bt->rchild)+1;
}

template <class DT>
void DispBiTree(BTNode<DT> * bt,int level)        // 显示树
{
	if(bt)                                        //空二叉树不显示
   { DispBiTree(bt->rchild,level+1);              //显示右子树
     cout<<endl;                                  //显示新行
     for(int i=0;i<level-1;i++)
        cout<<"   ";                              //确保在第level列显示节点
     cout<<bt->data;                              //显示节点
     DispBiTree(bt->lchild,level+1);              //显示左子树  
	 cout<<endl;
   }//if
}