实验8、二叉树的应用 (4学时)
(1)实验目的
通过该实验,使学生理解二叉树的链式存储,掌握二叉树的几种遍历算法,并通过该实验使学生理解递归的含义,掌握C语言编写递归函数的方法和注意事项。
(2)实验内容
实现教材中算法6.4描述的二叉树创建算法,在此基础上实现二叉树的先序、后序递归遍历算法、两种非递归中序遍历、层序遍历、求二叉树的深度。
(3)参考界面
(4)验收/测试用例
- 创建
输入 :
ABC$$DE$G$$F$$$
($表示空格)
输入对应的树如图所示:
- 先序 屏幕输出 A B C D E G F
- 后序 屏幕输出 C G E F D B A
- 中序 屏幕输出 C B E G D F A (两种中序非递归还需看源代码)
- 层序 屏幕输出 A B C D E F G
- 深度 屏幕显示 深度为5.
- 参考代码
#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; }