二叉树的基本操作(顺序二叉树)
该代码的二叉树结点是数字,采用的是用数组存储,一般使用在空结点较少的情况,使用的时候,一定要清楚二叉树元素在数组中的存储顺序特点,比如左右子树序号有什么特点,怎么由孩子结点的找到双亲节点……
如果想了解链式存储二叉树,可以参考http://www.cnblogs.com/-beyond/p/6200478.html
#include<iostream> #include<cmath> #include<cstdlib> using namespace std; const int MAX_TREE_SIZE=100; const int Nil=0; typedef int TElemType; typedef int SqBiTree[MAX_TREE_SIZE]; struct position{ //按满二叉树计算 int level,order; }; //函数声明 void show(); void InitBiTree(SqBiTree T); void DestroyBiTree(SqBiTree T); void CreateBiTree(SqBiTree T); int ClearBiTree(SqBiTree T); bool EmptyBiTree(SqBiTree T); int BiTreeDepth(SqBiTree T); TElemType BiTreeRoot(SqBiTree T); TElemType GetValue(SqBiTree T,position e); bool Assign(SqBiTree T,position e,TElemType value); TElemType Parent(SqBiTree T,TElemType e); TElemType LeftChild(SqBiTree T,TElemType e); TElemType RightChild(SqBiTree T,TElemType e); TElemType LeftSibling(SqBiTree T,TElemType e); TElemType RightSibling(SqBiTree T,TElemType e); void InsertChild(SqBiTree T,TElemType p,int LR,SqBiTree c); void Move(SqBiTree q,int j,SqBiTree T,int i); void PreOrderTraverse(SqBiTree T,int i); void InOrderTraverse(SqBiTree T,int i); void PostOrderTraverse(SqBiTree T,int i); void LevelOrderTraverse(SqBiTree T); void Print(SqBiTree T); int main(){ int x,LR,action; position p; TElemType e; SqBiTree T,s; show(); while(cin>>action){ switch(action){ case 1: system("cls"); InitBiTree(T); cout<<"初始化二叉树成功"<<endl<<endl; break; case 2: system("cls"); CreateBiTree(T); cout<<"二叉树创建成功"<<endl<<endl; break; case 3: system("cls"); cout<<"先序遍历二叉树,结果为:"<<endl; PreOrderTraverse(T,0); cout<<endl<<endl; break; case 4: system("cls"); cout<<"中序遍历二叉树,结果为:"<<endl; InOrderTraverse(T,0); cout<<endl<<endl; break; case 5: system("cls"); cout<<"后序遍历二叉树,结果为:"<<endl; PostOrderTraverse(T,0); cout<<endl<<endl; break; case 6: system("cls"); cout<<"层序遍历二叉树,结果为:"<<endl; LevelOrderTraverse(T); cout<<endl<<endl; break; case 7: system("cls"); cout<<"请输入层数和序号:"<<endl; cin>>p.level>>p.order; cout<<"第"<<p.level<<"层"<<" 第"<<p.order<<"个结点的值为: "<<GetValue(T,p); cout<<endl<<endl; break; case 8: system("cls"); ClearBiTree(T); cout<<"已清空二叉树"<<endl<<endl; break; case 9: InitBiTree(s); cout<<"请输入右子树为空的二叉树s:"<<endl; CreateBiTree(s); cout<<"待插入的二叉树已经建立,请输入将要插入的结点的值:"<<endl; cin>>e; cout<<"待插入的二叉树成为左孩子(0),右孩子(1):"<<endl; cin>>LR; InsertChild(T,e,LR,s); cout<<"操作成功"<<endl<<endl; break; case 10: system("cls"); cout<<"二叉树的各结点为:"<<endl; Print(T); cout<<endl; break; case 11: system("cls"); cout<<"请输入双亲结点"<<endl; cin>>e; cout<<"左孩子结点的值为: "<<LeftChild(T,e)<<endl; break; case 12: system("cls"); cout<<"请输入双亲结点"<<endl; cin>>e; cout<<"右孩子结点的值为: "<<RightChild(T,e)<<endl; break; case 13: system("cls"); cout<<"请输入右兄弟结点"<<endl; cin>>e; cout<<"左兄弟结点的值为: "<<LeftSibling(T,e)<<endl; break; case 14: system("cls"); cout<<"请输入左兄弟结点"<<endl; cin>>e; cout<<"右兄弟结点的值为: "<<RightSibling(T,e)<<endl; break; case 15: system("cls"); cout<<"请输入孩子结点"<<endl; cin>>e; cout<<"双亲结点的值为: "<<Parent(T,e)<<endl; break; case 16: system("cls"); cout<<"二叉树的深度为: "<<BiTreeDepth(T)<<endl; break; case 17: system("cls"); cout<<"根结点的值为: "<<BiTreeRoot(T)<<endl; break; case 18: system("cls"); cout<<"请输入结点的层数和在该层的序号: "<<endl; cin>>p.level>>p.order; cout<<"请输入将赋给该结点的值:"<<endl; cin>>e; Assign(T,p,e); cout<<"赋值成功!"<<endl; break; } system("pause"); system("cls"); show(); } } void show(){ cout<<"+-----------------------------------------------+"<<endl; 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<<"| 14->获取右兄弟 |"<<endl; cout<<"| 15->获取结点双亲 |"<<endl; cout<<"| 16->获取二叉树深度 |"<<endl; cout<<"| 17->获取根节点 |"<<endl; cout<<"| 18->给结点赋值 |"<<endl; cout<<"+-----------------------------------------------+"<<endl; } void InitBiTree(SqBiTree T){ int i; for(i=0;i<MAX_TREE_SIZE;i++){ T[i]=Nil;//初始值为Nil } } void DestroyBiTree(SqBiTree T){ int i; for(i=0;i<MAX_TREE_SIZE;i++){ T[i]=Nil;//初始值为Nil } } void CreateBiTree(SqBiTree T){ int i=0; cout<<"请按层需输入结点的值(数字),0表示空结点,以999结束,结点数<"<<MAX_TREE_SIZE<<":"<<endl; while(1){ cin>>T[i]; if(T[i]==999){ T[i]=Nil; break; } i++; } for(i=1;i<MAX_TREE_SIZE;i++){ if(i!=0 && T[(i+1)/2-1]==Nil && T[i]!=Nil){ cout<<"出现无双亲的非根节点!"<<endl; break; } } } int ClearBiTree(SqBiTree T){ int i; for(i=0;i<MAX_TREE_SIZE;i++){ T[i]=Nil;//初始值为Nil } } //判断二叉树是否为空 bool EmptyBiTree(SqBiTree T){ if(T[0]==Nil){ return true; } else { return false; } } //获取二叉树的深度 int BiTreeDepth(SqBiTree T){ int i=MAX_TREE_SIZE-1,j=0; while(i>=0){ //从后往前寻找到第一个结点不是默认值的下标 if(T[i]!=Nil){ break; } i--; } while(i>=pow(2,j)){ j++; } return j; } //获取根结点的值 TElemType BiTreeRoot(SqBiTree T){ if(EmptyBiTree(T)){ return Nil; } else { return T[0]; } } //获取给定结点e的值 TElemType GetValue(SqBiTree T,position e){ return T[int(pow(2,e.level-1)+e.order-2)]; } //给结点赋值 bool Assign(SqBiTree T,position e,TElemType value){ int i=pow(2,e.level-1)+e.order-2; if(value!=Nil && T[(i+1)/2-1]==Nil){ cout<<"非法操作,禁止给不含双亲的孩子赋非空值"<<endl; return false; } else if(value==Nil && (T[i*2+1]!=Nil || T[i*2+2]!=Nil)){ cout<<"非法操作,禁止给含有孩子的双亲赋空值"<<endl; return false; } T[i]=value; return true; } //获取双亲结点的值 TElemType Parent(SqBiTree T,TElemType e){ if(!EmptyBiTree(T)){ for(int i=0;i<=MAX_TREE_SIZE;i++){ if(T[i]==e){//判断结点e是否存在与二叉树中 return T[(i+1)/2-1]; } } } else { return Nil;//二叉树为空或者没有结点e } } //获取左孩子的值 TElemType LeftChild(SqBiTree T,TElemType e){ if(!EmptyBiTree(T)){ for(int i=0;i<MAX_TREE_SIZE;i++){ if(T[i]==e){//判断结点e是否存在与二叉树中 return T[i*2+1];//返回其左孩子的值 } } } else { return Nil;//二叉树为空或者没有结点e } } //获取右孩子的值 TElemType RightChild(SqBiTree T,TElemType e){ if(!EmptyBiTree(T)){ for(int i=0;i<MAX_TREE_SIZE;i++){ if(T[i]==e){//判断结点e是否存在与二叉树中 return T[i*2+2];//返回其左孩子的值 } } } else { return Nil;//二叉树为空或者没有结点e } } //获取左兄弟的值 TElemType LeftSibling(SqBiTree T,TElemType e){ if(!EmptyBiTree(T)){ for(int i=0;i<MAX_TREE_SIZE;i++){ if(T[i]==e && i%2==0){//判断结点e是否存在与二叉树中 //并且存在有兄弟,i%2=0为右孩子 return T[i-1];//返回其左兄弟的值 } } } else { return Nil;//二叉树为空或者没有结点e } } //获取右兄弟的值 TElemType RightSibling(SqBiTree T,TElemType e){ if(!EmptyBiTree(T)){ for(int i=0;i<MAX_TREE_SIZE;i++){ if(T[i]==e && i%2==1){//判断结点e是否存在与二叉树中 //并且存在有兄弟,i%2==1为左孩子 return T[i+1];//返回其右兄弟的值 } } } else { return Nil;//二叉树为空或者没有右兄弟 } } //仔细观察,寻找双亲、左右孩子和左右兄弟的方法都类似 //首先都得判断二叉树是否为空,然后再判断时候该结点是否存在 //最后根据判断返回结点值 //插入二叉树 void InsertChild(SqBiTree T,TElemType p,int LR,SqBiTree c){ //非空二叉树c要插到T中的p结点下面,成为p结点的(左或右)子树 //非空二叉树c与T无交集,且右子树为空,p结点原有的左或右子树成为s的右子树 //LR=0 c成为左子树,LR=1 c成为右子树 int i=0,j,k; //查找p结点的序号 //int temp=int(pow(2,BiTreeDepth(T))); //for(j=0;j<temp-1;j++){ // if(T[j]==p){ // break; // } //} //或者 for(j=0;j<MAX_TREE_SIZE;j++){ if(T[j]==p){ break; } } k=2*j+1+LR;//k为c子树将要插入的序号 if(T[k]!=Nil){ Move(T,k,T,2*k+2); } Move(c,i,T,k); } //移动二叉树 void Move(SqBiTree q,int j,SqBiTree T,int i){ //把从二叉树q的j结点开始的子树 移为 从二叉树T的i结点开始的子树 if(q[2*j+1]!=Nil){//q的左子树不为空 Move(q,(2*j+1),T,(2*i+1)); } if(q[2*j+2]!=Nil){//q的右子树不为空 Move(q,(2*j+2),T,(2*i+2)); } T[i]=q[j]; q[i]=Nil; } //先序遍历 void PreOrderTraverse(SqBiTree T,int i){ cout<<T[i]<<' '; if(T[2*i+1]!=Nil){ PreOrderTraverse(T,2*i+1); } if(T[2*i+2]!=Nil){ PreOrderTraverse(T,2*i+2); } } //中序遍历 void InOrderTraverse(SqBiTree T,int i){ if(T[2*i+1]!=Nil){ InOrderTraverse(T,2*i+1); } cout<<T[i]<<' '; if(T[2*i+2]!=Nil){ InOrderTraverse(T,2*i+2); } } //后序遍历 void PostOrderTraverse(SqBiTree T,int i){ if(T[2*i+1]!=Nil){ PostOrderTraverse(T,2*i+1); } if(T[2*i+2]!=Nil){ PostOrderTraverse(T,2*i+2); } cout<<T[i]<<' '; } //层序遍历 void LevelOrderTraverse(SqBiTree T){ int i=MAX_TREE_SIZE-1; while(T[i]==Nil){ i--; } for(int j=0;j<=i;j++){ if(T[j]!=Nil){ cout<<T[j]<<' '; } } cout<<endl; } //逐层按本层序号输出二叉树 void Print(SqBiTree T){ int j,k; position p; TElemType e; for(j=1;j<=BiTreeDepth(T);j++){ cout<<"第"<<j<<"层: "; for(k=1;k<=pow(2,j-1);k++){ p.level=j; p.order=k; e=GetValue(T,p); cout<<k<<":"<<e<<" "; } cout<<endl; } cout<<endl; }
如需转载,请注明文章出处,谢谢!!!