包含二叉树全部操作的代码及其注释(从二叉树的建立,到七种遍历方式,再到各种操作)

本程序集二叉树各种操作于一体
1.递归形式的前序遍历,中序遍历,后序遍历
2.非递归形式的前序遍历,中序遍历,后序遍历
3.二叉树的建立
4.二叉树上各种操作的实现
读者可以直接根据函数头和说明直接调用或者调试,对每种操作的算法解释,在其它的博客中(点击上方链接即可),欢迎借鉴学习

函数头

//按前序遍历建立一颗带头节点的二叉树 
template <typename T> BiTree<T> *createBiTree();
//递归先序遍历二叉树
template<typename T>  void preOrder(BiTree<T> *bt);
//递归中序遍历二叉树
template<typename T>  void inOrder(BiTree<T> *bt);
//递归后序遍历二叉树
template<typename T>  void postOrder(BiTree<T> *bt);
 //队列实现二叉树层序遍历
template<typename T> void levelOrder(BiTree<T> *bt);
//非递归方法中序遍历二叉树
template<typename T> void inOrderNR(BiTree<T> *bt) ;
//非递归方法前序遍历二叉树
template<typename T> void preOrderNR(BiTree<T> *bt);
//非递归方法后序递归二叉树
template<typename T> void postOrderNR(BiTree<T> *bt);
//访问根节点 
template<typename T> void visit(BiTree<T> *bt); 
//求二叉树bt子树深度的递归算法 
template<typename T> int getDepth(BiTree<T> *bt);
//在二叉树bt中查找数据元素值为data的节点,
//查找成功,返回指向该节点的指针,失败返回空指针 
template<typename T> BiTree<T> *getData( BiTree<T> *bt,T data);
//统计二叉树bt中叶子节点的个数 
template<typename T> int countLeaf(BiTree<T> *bt);
//非递归方法中序遍历二叉树来计算统计二叉树叶子节点个数 
template<typename T> int countLeafNR(BiTree<T> *bt) ;
//利用二叉树的性质计算二叉树bt中度为2的节点的个数 
template<typename T> int countDegreeTwo(BiTree<T> *bt) ;
//非递归中序遍历二叉树,统计二叉树中度为1的节点个数 
template<typename T> int countDegreeOne(BiTree<T> *bt) ;
//非递归中序遍历二叉树,统计二叉树中所有节点的个数 
template<typename T> int countNode(BiTree<T> *bt) ;
//非递归中序遍历获得二叉树bt中数据的最大值 
template<typename T> T getMaxVal(BiTree<T> *bt); 
//非递归中序遍历获得二叉树bt中数据的最小值 
template<typename T> T getMinVal(BiTree<T> *bt); 

完整代码


#include<bits/stdc++.h>
using namespace std;

const char flag = '#';
//二叉树节点结构体定义 
template <typename T=double>  
struct BiTree{
    
    
	T data;
	BiTree<T> *left,//左子树 
	          *right;//右子树
	//构造函数 
	BiTree(){
    
     left = right = NULL;	} 
	BiTree(const T &theData){
    
      data = theData;left = right = NULL;}
	BiTree(const T theData,BiTree *theLeft,BiTree *theRight)
	{
    
    data = theData;left=theLeft;right = theRight;	}
};

//按前序遍历建立一颗带头节点的二叉树 
template <typename T> BiTree<T> *createBiTree();
//递归先序遍历二叉树
template<typename T>  void preOrder(BiTree<T> *bt);
//递归中序遍历二叉树
template<typename T>  void inOrder(BiTree<T> *bt);
//递归后序遍历二叉树
template<typename T>  void postOrder(BiTree<T> *bt);
 //队列实现二叉树层序遍历
template<typename T> void levelOrder(BiTree<T> *bt);
//非递归方法中序遍历二叉树
template<typename T> void inOrderNR(BiTree<T> *bt) ;
//非递归方法前序遍历二叉树
template<typename T> void preOrderNR(BiTree<T> *bt);
//非递归方法后序递归二叉树
template<typename T> void postOrderNR(BiTree<T> *bt);
//访问根节点 
template<typename T> void visit(BiTree<T> *bt); 
//求二叉树bt子树深度的递归算法 
template<typename T> int getDepth(BiTree<T> *bt);
//在二叉树bt中查找数据元素值为data的节点,
//查找成功,返回指向该节点的指针,失败返回空指针 
template<typename T> BiTree<T> *getData( BiTree<T> *bt,T data);
//统计二叉树bt中叶子节点的个数 
template<typename T> int countLeaf(BiTree<T> *bt);
//非递归方法中序遍历二叉树来计算统计二叉树叶子节点个数 
template<typename T> int countLeafNR(BiTree<T> *bt) ;
//利用二叉树的性质计算二叉树bt中度为2的节点的个数 
template<typename T> int countDegreeTwo(BiTree<T> *bt) ;
//非递归中序遍历二叉树,统计二叉树中度为1的节点个数 
template<typename T> int countDegreeOne(BiTree<T> *bt) ;
//非递归中序遍历二叉树,统计二叉树中所有节点的个数 
template<typename T> int countNode(BiTree<T> *bt) ;
//非递归中序遍历获得二叉树bt中数据的最大值 
template<typename T> T getMaxVal(BiTree<T> *bt); 
//非递归中序遍历获得二叉树bt中数据的最小值 
template<typename T> T getMinVal(BiTree<T> *bt); 
int main()
{
    
    
	BiTree<char> *bt;
	cout<<" 用前序遍历创建二叉树:"; 
	bt = createBiTree<char>();
	cout<<" 对遍历的测试" <<endl;
	cout<<" 前序遍历结果:"; preOrder(bt);cout<<endl;				
	cout<<" 中序遍历结果:"; inOrder(bt);cout<<endl;	
	cout<<" 后序遍历结果:"; postOrder(bt);	cout<<endl;
	
	cout<<" 非递归前序遍历结果:"; preOrderNR(bt);cout<<endl;
	cout<<" 非递归中序遍历结果:"; inOrderNR(bt) ;cout<<endl; 
	cout<<" 非递归后序遍历结果:"; postOrderNR(bt);cout<<endl;	
	
	cout<<" 层次遍历结果:";	levelOrder(bt); cout<<endl;
    cout<<endl; 
    cout<<" 对相关操作的测试" <<endl;
    cout<<" 递归方法统计二叉树叶子节点个数为:"<<countLeaf(bt)<<endl; 
    cout<<" 用递归求得二叉树bt子树深度为:"<<getDepth(bt)<<endl;
    char x = 'G'; 
   //cout<<" 递归查找"<<x<<" 的子树深度为:"<<getDepth(getData(bt,x))<<endl; 
    cout<<" 递归查找值为"<<x<<" 的节点的值为:"<<getData(bt,x)->data<<endl; 

    //cout<<" 非递归方法统计"<<endl;
   	cout<<" 该二叉树总的节点个数为:"<<countNode(bt)<<endl; 
	cout<<" 该二叉树叶子节点个数为:"<<countLeafNR(bt)<<endl; 
	cout<<" 该二叉树度为1节点个数为:"<<countDegreeOne(bt)<<endl; 
	cout<<" 该二叉树度为2节点个数为:"<<countDegreeTwo(bt)<<endl;
	cout<<" 该二叉树中数值最大值为:"<<getMaxVal(bt)<<endl; 
	cout<<" 该二叉树中数值最小值为:"<<getMinVal(bt)<<endl; 
    
	
	
	
	
	
	
 } 
 
 // A B C # # D E # G # # F # # # 
 //zmooc A B D # # F E # # # C G # H # # I # # 
 //非递归中序遍历获得二叉树bt中数据的最大值 
 //非递归中序遍历二叉树,统计二叉树中所有节点的个数 
template<typename T> int countNode(BiTree<T> *bt) {
    
    
	int ans ; 
	stack<BiTree<T>*  > s;   //创建栈 
	BiTree<T> *p = bt;       //创建临时指针p 
	
	while(p || !s.empty())
	{
    
    
		while(p != NULL)    /*一直向左并将沿途结点压入堆栈*/
		{
    
    
			s.push(p) ;
			p = p->left;
		}
				
		//visit(s.top());//访问根结点			
		ans++;
		
		p = s.top();  // p要指向此时s的栈顶元素,否则p=NULL,程序就会出错 
		s.pop();      //结点出栈 
		p = p->right; // 转向右子树								
	}
	return ans;
	
}
template<typename T> T getMaxVal(BiTree<T> *bt){
    
    
	T ans = bt->data; 
	stack<BiTree<T>*  > s;   //创建栈 
	BiTree<T> *p = bt;       //创建临时指针p 
	
	while(p || !s.empty())
	{
    
    
		while(p != NULL)    /*一直向左并将沿途结点压入堆栈*/
		{
    
    
			s.push(p) ;
			p = p->left;
		}
				
		//visit(s.top());//访问根结点			
		if(ans <= s.top()->data)
		   ans = s.top()->data; 
		
		p = s.top();  // p要指向此时s的栈顶元素,否则p=NULL,程序就会出错 
		s.pop();      //结点出栈 
		p = p->right; // 转向右子树								
	}
	return ans;
} 
//非递归中序遍历获得二叉树bt中数据的最小值 
template<typename T> T getMinVal(BiTree<T> *bt){
    
    
		T ans = bt->data; 
	stack<BiTree<T>*  > s;   //创建栈 
	BiTree<T> *p = bt;       //创建临时指针p 
	
	while(p || !s.empty())
	{
    
    
		while(p != NULL)    /*一直向左并将沿途结点压入堆栈*/
		{
    
    
			s.push(p) ;
			p = p->left;
		}
				
		//visit(s.top());//访问根结点			
		if(ans > s.top()->data)
		   ans = s.top()->data; 
		
		p = s.top();  // p要指向此时s的栈顶元素,否则p=NULL,程序就会出错 
		s.pop();      //结点出栈 
		p = p->right; // 转向右子树								
	}
	return ans;
} 
 //利用二叉树的性质计算二叉树bt中度为2的节点的个数 
template<typename T> int countDegreeTwo(BiTree<T> *bt) {
    
    
	return countLeaf(bt) - 1;
}
 //非递归方法中序遍历二叉树来计算统计二叉树叶子节点个数 
template<typename T> int countLeafNR(BiTree<T> *bt) 
{
    
       int count = 0; 
	stack<BiTree<T>*  > s;   //创建栈 
	BiTree<T> *p = bt;       //创建临时指针p 
	
	while(p || !s.empty())
	{
    
    
		while(p != NULL)    /*一直向左并将沿途结点压入堆栈*/
		{
    
    
			s.push(p) ;
			p = p->left;
		}
				
		//visit(s.top());//访问根结点			
		if(s.top()->right == NULL && s.top()->left == NULL)//访问的时候检测是否为叶子节点 
		count++; 	
		
		p = s.top();  // p要指向此时s的栈顶元素,否则p=NULL,程序就会出错 
		s.pop();      //结点出栈 
		p = p->right; // 转向右子树								
	}
	return count;
}
//非递归——中序遍历二叉树统计二叉树中度为2的节点个数 
template<typename T> int countDegreeOne(BiTree<T> *bt) 
{
    
       int count = 0; 
	stack<BiTree<T>*  > s;   //创建栈 
	BiTree<T> *p = bt;       //创建临时指针p 
	
	while(p || !s.empty())
	{
    
    
		while(p != NULL)    /*一直向左并将沿途结点压入堆栈*/
		{
    
    
			s.push(p) ;
			p = p->left;
		}
				
		//visit(s.top());//访问根结点			
		if(s.top()->right == NULL ^ s.top()->left == NULL)//访问的时候检测是否为叶子节点 
		count++; 	
		
		p = s.top();  // p要指向此时s的栈顶元素,否则p=NULL,程序就会出错 
		s.pop();      //结点出栈 
		p = p->right; // 转向右子树
		
		
				
	}
	return count;
}
//队列实现二叉树层序遍历
template<typename T> void levelOrder(BiTree<T> *bt)
{
    
    
	queue<BiTree<T> *> q;       //声明队列q,类型为二叉树节点的指针 
	if(bt == NULL )            //如果二叉树为空,直接退出 
	{
    
    
		return ;
	 } 
	q.push(bt);
    while(!q.empty())          //队列非空时 
    {
    
     
	visit(q.front());          //访问队首节点 
    
    if(q.front()->left != NULL)//队首结点的左孩子进队列 
	  q.push(q.front()->left);
	if(q.front()->right != NULL)//队首节点的右孩子进队 
	  q.push(q.front()->right);	  
	  
	  q.pop();                 //队首结点出队列 
	}
	
} 
//非递归方法中序遍历二叉树
template<typename T> void inOrderNR(BiTree<T> *bt) 
{
    
    
	stack<BiTree<T>*  > s;   //创建栈 
	BiTree<T> *p = bt;       //创建临时指针p 
	
	while(p || !s.empty())
	{
    
    
		while(p != NULL)    /*一直向左并将沿途结点压入堆栈*/
		{
    
    
			s.push(p) ;
			p = p->left;
		}
		visit(s.top());//访问根结点	
		p = s.top();  // p要指向此时s的栈顶元素,否则p=NULL,程序就会出错 
		s.pop();      //结点出栈 
		p = p->right; // 转向右子树 
				
	}
}
//非递归方法前序遍历二叉树
template<typename T> void preOrderNR(BiTree<T> *bt)
{
    
    
	stack<BiTree<T>* > s;
	BiTree<T> *p = bt;
	
	while(p ||  !s.empty())  //指针p不为空或者s不为空,循环一直进行下去 
	{
    
    
		while(p)
		{
    
    
			s.push(p);
			visit(p);        //访问根节点 
			p = p->left;
		}
		p = s.top();
		s.pop();
		p = p->right;
	}
 } 
//非递归方法后序递归二叉树
template<typename T> void postOrderNR(BiTree<T> *bt){
    
    
    stack<BiTree<T>*  > s;   
	BiTree<T> *p = bt;       
	BiTree<T> *pre = nullptr; //增加一指向前一结点的指针 
	while(p || !s.empty())
	{
    
    
		while(p != NULL)    /*一直向左并将沿途结点压入堆栈*/
		{
    
    
			s.push(p) ;
			p = p->left;
		}
		p = s.top();
		if(pre == p->right || p->right == NULL) //如果栈顶结点的右 
		{
    
      
		   visit(p);
		   pre = p;           //pre指向上一次访问的结点 
		   s.pop(); 
		   p = nullptr; 	  //这里的p如果直接指向栈顶元素的有结点(即p=s.top())
		                      //将会导致循环出不去,也就是到最后一个	
		} 
		else
		 {
    
    	  
		   p = p->right;
		 }	
	}
} 
 //按前序遍历建立一颗带头节点的二叉树 
template <typename T> BiTree<T> *createBiTree()
{
    
    
	T data;
	cin >> data;
	if(data == flag)
	{
    
    
		return NULL;
	}
	else
	{
    
    
		BiTree<T> *bt ;
		bt = new BiTree<T>(data,createBiTree<T>(),createBiTree<T>());	
	    return bt;
	}
}
//递归先序遍历二叉树
template<typename T>  void preOrder(BiTree<T> *bt)
{
    
    
	if(bt == NULL)      //递归调用的结束条件 
	return ;
	
	visit(bt);          //访问树根 
	preOrder(bt->left); //先序遍历递归左子树
	preOrder(bt->right);// 先序遍历递归右子树 
}
//递归后序遍历二叉树
template<typename T>  void postOrder(BiTree<T> *bt)
{
    
    
	if(bt == NULL)      //递归调用的结束条件 
	return ;
	 
	postOrder(bt->left); //后序遍历递归左子树
	postOrder(bt->right);//后序遍历递归右子树 
	visit(bt);          //访问树根
}
//递归中序遍历二叉树
template<typename T>  void inOrder(BiTree<T> *bt)
{
    
     
	if(bt == NULL)      //递归调用的结束条件 
	return ;
	inOrder(bt->left);  //中序遍历递归左子树
	visit(bt);          //访问树根
	inOrder(bt->right); // 中序遍历递归右子树 
	
}

//统计二叉树bt中叶子节点的个数 
template<typename T> int countLeaf(BiTree<T> *bt){
    
    
	//bt为根节点,返回值为bt的叶子节点个数 
	if(bt == NULL) return 0;
	if(bt->left == NULL && bt->right == NULL)
	 return 1;     //左节点为空,右节点为空,则bt为叶子节点,返回1
	
	return countLeaf(bt->left) + countLeaf(bt->right); 
} 

//在二叉树bt中查找数据元素值为data的节点,
//查找成功,返回指向该节点的指针,失败返回空指针 
template<typename T> BiTree<T> *getData( BiTree<T> *bt,T data)
{
    
    
	BiTree<T> *p = bt;         //设置一个临时指针,便于判断 
	 
	
	if(bt!= NULL)
	{
    
    
	if(p->data == data)       //查找成功返回 
	return p;
	if(bt->left != NULL)      //若有左子树 ,在左子树中查找 
	{
    
    
	 p = getData(bt->left,data);
	if(p!= NULL)               //若查找到了,返回结果 
	return p;
	}
	
	if(bt->right != NULL)     //若有右子树,在右子树中查找 
	{
    
    
	p = getData(bt->right,data);
	if(p!=NULL)               //若查找到了,返回结果 
	return p;
	}
	}
	
	return nullptr;              //查找失败,返回NULL  
}

//求二叉树bt子树深度的递归算法 
template<typename T> int getDepth(BiTree<T> *bt)
{
    
    
	
	if(bt == NULL) 
	return 0;
	
	int l = getDepth(bt->left);
	int r = getDepth(bt->right);
	
	return (r>l? r: l) +1;
 } 
 
//访问根节点 
template<typename T> void visit(BiTree<T> *bt)
{
    
    
	cout<<bt->data<<" ";
 } 

结果分析

在这里插入图片描述

友情链接

二叉树前序中序后序遍历的介绍及其递归形式的代码

猜你喜欢

转载自blog.csdn.net/qq_45768060/article/details/105801550
今日推荐