实验8、二叉树的应用 (4学时)

 

实验8、二叉树的应用 (4学时)

(1)实验目的

通过该实验,使学生理解二叉树的链式存储,掌握二叉树的几种遍历算法,并通过该实验使学生理解递归的含义,掌握C语言编写递归函数的方法和注意事项。

(2)实验内容

实现教材中算法6.4描述的二叉树创建算法,在此基础上实现二叉树的先序、后序递归遍历算法、两种非递归中序遍历、层序遍历、求二叉树的深度。

(3)参考界面

 

(4)验收/测试用例

  1. 创建

输入 :

ABC$$DE$G$$F$$$     

  ($表示空格)

输入对应的树如图所示:

 

  1. 先序   屏幕输出  A B C D E G F
  2. 后序   屏幕输出  C G E F D B A
  3. 中序   屏幕输出  C B E G D F A     (两种中序非递归还需看源代码)
  4. 层序   屏幕输出  A B C D E F G
  5. 深度   屏幕显示 深度为5.
  6. 参考代码
    #include <iostream>
    #include <cmath>
    #include <algorithm>
    #include <cstring>
    #include <string>
    #include <queue>
    #define Status int
    #define OK 1
    #define False 0
    #define ll long long
    #define Datatype char 
    using namespace std;
    typedef struct node
    {
    	Datatype data;//数据
    	struct node *lchild,*rchild;//指向左右孩子的指针 
    }BitNode,*Bitree; //Bitree是node结构指针的别名,代表指向BitNode结构体类型的指针
    
    //初始化,构造空二叉树 
    Status Init_Bitree(Bitree &T)
    {
    	T=NULL;
    	return OK;
    } 
    /*T是类型是 Bitree 所以T是一个指针*/
    //销毁二叉树   
    Status Destory_Bitree(Bitree &T)
    {
    	if(T)//利用递归 
    	{
    		if(T->lchild)//如果有左孩子
    			Destory_Bitree(T->lchild);
    		if(T->rchild)//如果有右孩子 
    			Destory_Bitree(T->rchild); 
    		free(T);
    		T=NULL; 
    	}
    	return OK;
    } 
    //int cnt=0;
    //创建二叉树 
    void Create_Bitree(Bitree &T)
    {
    	char ch;
    	cin>>ch;
    	if(ch=='#') T=NULL;
    	else
    	{
    		T=(BitNode*)malloc(sizeof(BitNode));
    		T->data=ch;
    		Create_Bitree(T->lchild);
    		Create_Bitree(T->rchild);		
    	}
    //	return OK;	
    }
    
    //清空二叉树
    Status Clear_Bitree(Bitree &T)
    {
    	if(T==NULL)
    	{
    		return OK;
    	}
    	Clear_Bitree(T->lchild);
    	Clear_Bitree(T->rchild);
    	free(T);
    }
    
    //判断二叉树是否为空
    Status Empty_Bitree(Bitree &T)
    {
    	if(T==NULL) return OK;
    	else return False;
    } 
    
    //二叉树的深度
    Status Depth_Bitree(Bitree T)
    {
    	int hl=0,hr=0;
    	if(T==NULL) return 0;
    	else
    	{
    		hl=Depth_Bitree(T->lchild); 
    		hr=Depth_Bitree(T->rchild);//递归,先左后右 
    		return max(hl,hr)+1;
    	}
    }
    
    //Root_ 返回T的根
    Datatype Root_Bitree(Bitree T)
    {
    	if(T==NULL) return 0;
    	else return T->data;
    } 
    
    //返回某个结点的值
    Datatype Value_Bitree(Bitree p)
    {
    	return p->data;
    } 
    //结点总数 
    int Count_Bitree(Bitree T)
    {
    	if(T)
    	{
    		return Count_Bitree(T->lchild)+Count_Bitree(T->rchild)+1;
    	}else return 0;
     } 
    //叶子结点
    int Leaves_Bitree(Bitree T)
    {
    	if(T==NULL) return 0;
    	if(T->lchild==NULL&&T->rchild==NULL)
    		return 1;
    	else return Leaves_Bitree(T->lchild)+Leaves_Bitree(T->rchild);
     } 
    //返回节点的双亲
    Datatype Parent_Bitree(Bitree T,Datatype e)
    {
    	if(T)
    	{
    		queue<Bitree> q;
    		while(!q.empty()) q.pop();//清空
    		q.push(T);//根 入队 
    		while(!q.empty()) 
    		{
    			Bitree temp=q.front();//取出队首 
    			q.pop();
    			if((temp->lchild&&temp->lchild->data==e)||(temp->rchild&&temp->rchild->data==e))
    				return temp->data;
    			else 
    			{
    				if(temp->lchild)
    					q.push(temp->lchild);
    				if(temp->rchild)
    					q.push(temp->rchild);
    			}
    		 } 
    	}
        return False;	
    } 
    //返回某个值在数中的节点的指针 
    Bitree NodePoint_Bitree(Bitree T,Datatype e)
    {
    	if(T==NULL) return False;
    	Bitree P;
    	queue<Bitree> q;
    	while(!q.empty()) q.pop();
    	P=T;
    	q.push(P);
    	while(!q.empty())
    	{
    		Bitree temp=q.front();
    		q.pop();
    		if(temp->data==e) return temp;
    		if(temp->lchild) q.push(temp->lchild);
    		if(temp->rchild) q.push(temp->rchild);
    	}
    	return False;//说明没找到 
    }
    //返回节点的左孩子 
    Datatype LeftChild_Bitree(Bitree p)
    {
    	if(p->lchild)
    	{
    		return p->lchild->data;
    	}
    	else return False;
    }
    //返回节点的右孩子 
    Datatype RightChild_Bitree(Bitree p)
    {
    	if(p->rchild)
    	{
    		return p->rchild->data;
    	}
    	else return False;
    }
    //返回节点的左兄弟 
    Datatype LeftSibing_Bitree(Bitree T,Datatype e)
    {
    	Bitree P;
    	Init_Bitree(P);
    	if(T)
    	{
    		P=NodePoint_Bitree(T,Parent_Bitree(T,e));
    		if(P->lchild&&P->rchild&&P->rchild->data==e)
    		 return P->lchild->data;
    	}else return False;
    }
    //返回节点的右兄弟
    Datatype RightSibing_Bitree(Bitree T,Datatype e)
    {
    	Bitree P;
    	Init_Bitree(P);
    	if(T)
    	{
    		P=NodePoint_Bitree(T,Parent_Bitree(T,e));
    		if(P->lchild&&P->rchild&&P->lchild->data==e)
    			return P->rchild->data;
    	}else return False;
     } 
    //给结点赋值
    void Assign_Bitree(Bitree p,Datatype value)
    {
    	p->data=value;
    }
    
    //先序遍历 
    void PreOrderTraverse(Bitree T,int level)
    {
    	if(T)
    	{
    		cout<<T->data<<" "<<level<<endl;//访问根节点 
    		PreOrderTraverse(T->lchild,level+1);//先遍历左子树
    		PreOrderTraverse(T->rchild,level+1);//最后再遍历右子树 
    	}
    }
    //中序遍历 
    void InOrderTraverse(Bitree T,int level)
    {
    	if(T)
    	{
    		InOrderTraverse(T->lchild,level+1);//先遍历左子树 
    		cout<<T->data<<" "<<level<<endl;//再访问根节点
    		InOrderTraverse(T->rchild,level+1);//最后遍历右子树 
    	}
    }
    //后序遍历
    void  PostOrderTraverse(Bitree T,int level)
    {
    	if(T)
    	{
    		PostOrderTraverse(T->lchild,level+1);//先访问左子树 
    		PostOrderTraverse(T->rchild,level+1);//再访问右子树 
    		cout<<T->data<<" "<<level<<endl;//最后访问根节点 
    	}
    }
    //删除子树
    /*LR==0 代表 左子树 LR==1 代表右子树*/ 
    Status DeleteChild_Bitree(Bitree P,int LR)
    {
    	if(LR==0)
    	{
    		if(P->lchild)
    		{
    			Destory_Bitree(P->lchild);
    			return OK;
    		}
    	}else if(LR==1)
    	{
    		if(P->rchild)
    		{
    			Destory_Bitree(P->rchild);
    			return OK;
    		}
    	}return False;
     } 
    //插入子树
    Status InsertChild_Bitree(Bitree P,int LR,Bitree c)
    {
    	if(P)
    	{
    		if(LR==0)
    		{
    			c->rchild=P->lchild;
    			P->lchild=c;
    		}else if(LR==1)
    		{
    			c->rchild=P->rchild;
    			P->rchild=c;
    		}
    		return OK;
    	}else return False;
     } 
    void visit()
    {
    	cout<<"***********************"<<endl;
    	cout<<"**    1.建立二叉树   **"<<endl;
    	cout<<"**    2.清空二叉树   **"<<endl;
    	cout<<"**    3.销毁二叉树   **"<<endl;
    	cout<<"**  4.先序遍历二叉树 **"<<endl;
    	cout<<"**  5.中序遍历二叉树 **"<<endl;
    	cout<<"**  6.后序遍历二叉树 **"<<endl;
    	cout<<"**  7.二叉树的高度   **"<<endl;
    	cout<<"**  8.二叉树结点数   **"<<endl;
    	cout<<"**  9.二叉树叶子数   **"<<endl;
    	cout<<"** 10.结点的左右孩子 **"<<endl;
    	cout<<"** 11.结点的左右兄弟 **"<<endl;
    	cout<<"**   12.结点的双亲   **"<<endl;
    	cout<<"**      13.退出      **"<<endl; 
    	cout<<"***********************"<<endl; 
     } 
    int main()
    {
    	visit();
    	Bitree Tree;
    	Init_Bitree(Tree);
    	int opt;
    	cout<<"输入你想进行的操作:";
    	while(cin>>opt)
    	{
    		switch(opt)
    		{
    			case 1://创建
    				cout<<"创建二叉树:"; 
    				Create_Bitree(Tree); 
    				cout<<"创建成功"<<endl;
    				break;
    			case 2://清空 
    				if(Clear_Bitree(Tree))
    					cout<<"清空成功"<<endl;
    				else cout<<"清空失败"<<endl; 
    				break;
    			case 3://销毁 
    				if(Destory_Bitree(Tree))
    					cout<<"销毁成功"<<endl;
    				else cout<<"销毁失败"<<endl; 
    				break;
    			case 4://先序 
    				cout<<"先序遍历:"<<endl;
    				PreOrderTraverse(Tree,1);
    				cout<<endl;
    				break;
    			case 5://中序 
    				cout<<"中序遍历:"<<endl;
    				InOrderTraverse(Tree,1);
    				cout<<endl;
    				break;
    			case 6://后序 
    				cout<<"后序遍历:"<<endl; 
    				PostOrderTraverse(Tree,1); 
    				cout<<endl;
    				break;
    			case 7://高度 
    				cout<<"高度: ";
    				cout<<Depth_Bitree(Tree)<<endl;
    				break;
    			case 8:
    				cout<<"结点数: ";
    				cout<<Count_Bitree(Tree)<<endl;
    				break;
    			case 9:
    				cout<<"叶子结点数: ";
    				cout<<Leaves_Bitree(Tree)<<endl;
    				break; 
    			case 10://左右孩子 
    				cout<<"输入你想查找的结点值:";
    				Datatype e;
    				cin>>e;
    				Bitree p;
    				Init_Bitree(p);
    				p=NodePoint_Bitree(Tree,e); 
    				if(LeftChild_Bitree(p))
    				{
    					cout<<"左子树:"<<LeftChild_Bitree(p)<<endl; 
    				}else cout<<"左子树:"<<"不存在"<<endl;
    				if(RightChild_Bitree(p))
    				{
    					cout<<"右子树:"<<RightChild_Bitree(p)<<endl; 
    				}else cout<<"右子树:"<<"不存在"<<endl;
    				break;
    			case 11:
    				cout<<"输入你想查找的结点值:";
    				Datatype val;
    				cin>>val;
    				if(LeftSibing_Bitree(Tree,val))
    				{
    					cout<<"左兄弟:"<<LeftSibing_Bitree(Tree,val)<<endl;
    				 } else cout<<"左兄弟:"<<"不存在"<<endl;
    				if(RightSibing_Bitree(Tree,val))
    				{
    					cout<<"右兄弟:"<<RightSibing_Bitree(Tree,val)<<endl;
    				}else cout<<"右兄弟:"<<"不存在"<<endl;
    			case 12://双亲 
    				Datatype c;
    				cout<<"输入你想查找的结点:";
    				cin>>c; 
    				if(Parent_Bitree(Tree,c))
    				{
    					cout<<Parent_Bitree(Tree,c)<<endl;
    				}else cout<<"不存在"<<endl;
    				break;
    			case 13:
    				cout<<"Exit"<<endl;
    				return 0;
    		}
    		cout<<"输入你想进行操作的序号:"<<endl; 
    	 } 
    	return 0;
    }
    

     

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值