二叉树的所有操作
#include<iostream> #include<stdio.h> #include<malloc.h> using namespace std; #define MaxSize 100 #define MaxWidth 40 typedef char ElemType; typedef struct Node2 { char data;//数据域 struct Node2*lchild,*rchild;//左指针域,右指针域 }BTNode; void CreateBTNode(BTNode *&b,char *str)//由str串创建二叉链 { BTNode *St[MaxSize],*p=NULL; int top=-1,k,j=0; char ch; b=NULL;//建立二叉链初始时为空 ch=str[j]; while(ch!='\0')//str未扫描完时循环 { switch(ch) { case'(':top++;St[top]=p;k=1;break;//为左结点 case')':top--;break; case',':k=2;break;//为右结点 default:p=(BTNode *)malloc(sizeof(BTNode)); p->data=ch; p->lchild=p->rchild=NULL; if(b==NULL)//p指向二叉树的根结点 b=p; else//已建立二叉树根结点 { switch(k) { case 1:St[top]->lchild=p;break; case 2:St[top]->rchild=p;break; } } } j++; ch=str[j]; } } void createbitree(BTNode *&T)//先序产生二叉树 { char ch; scanf("%c",&ch); if(ch==' ')T=NULL; else { T=(BTNode*)malloc(sizeof(BTNode)); T->data=ch; createbitree(T->lchild); createbitree(T->rchild); } } BTNode *CreateBT1(char *pre,char *in,int n)//由先序和中序遍历序列构造二叉树 { BTNode *s; char *p; int k; if(n<=0)return NULL; s=(BTNode *)malloc(sizeof(BTNode));//创建二叉树结点*s s->data=*pre; for(p=in;p<in+n;p++)//在中序序列中找等于*pre的位置k if(*p==*pre) break; k=p-in; s->lchild=CreateBT1(pre+1,in,k); s->rchild=CreateBT1(pre+k+1,p+1,n-k-1); return s; } BTNode *CreateBT2(char *post,char *in,int n,int m)//由中序和后序遍历序列构造二叉树 { BTNode *s; char *p,*q,*maxp; int maxpost,maxin,k; if(n<=0)return NULL; maxpost=-1; for(p=in;p<in+n;p++)//求in的全部字符中在post最右边的那个字符 for(q=post;q<post+m;q++)//在in中用maxp指向这个字符,用maxin标志它在in中的下标 if(*p==*q) { k=q-post; if(k>maxpost) { maxpost=k; maxp=p; maxin=p-in; } } s=(BTNode *)malloc(sizeof(BTNode));//创建二叉树结点*s s->data=post[maxpost]; s->lchild=CreateBT2(post,in,maxin,m); s->rchild=CreateBT2(post,maxp+1,n-maxin-1,m); return s; } void DispLeaf(BTNode *b) //输出一颗给二叉树放入所有叶子结点 { if(b!=NULL) { if(b->lchild==NULL&&b->rchild==NULL) printf("%c",b->data); else { DispLeaf(b->lchild); DispLeaf(b->rchild); } } } BTNode*InsertLeftNode(BTNode *p,char x)//左结点插入 { BTNode *s,*t; if(p==NULL) return NULL; t=p->lchild; s=(BTNode*)malloc(sizeof(BTNode)); s->data=x; s->lchild=t; s->rchild=NULL; p->lchild=s; return p->lchild; } BTNode*InsertRightNode(BTNode *p,char x)//右结点插入 { BTNode *s,*t; if(p==NULL) return NULL; t=p->rchild; s=(BTNode*)malloc(sizeof(BTNode)); s->data=x; s->rchild=t; s->lchild=NULL; p->rchild=s; return p->rchild; } BTNode *DleteLeaftTree(BTNode *p)//删除左结点 { BTNode *q; if(p==NULL||p->lchild==NULL) return NULL; q=p->lchild; p->lchild=NULL; free(q); q=NULL; return p; } BTNode *DleteRightTree(BTNode *p)//删除右结点 { BTNode *q; if(p==NULL||p->rchild==NULL) return NULL; q=p->rchild; p->rchild=NULL; free(q); q=NULL; return p; } BTNode *SearchNode(BTNode *b,char x)//查找结点 { BTNode *p; if(b==NULL) return NULL; else if (b->data==x) return b; else { p=SearchNode(b->lchild,x); if(p!=NULL) return p; else return SearchNode(b->rchild,x); } } BTNode *lchildNode(BTNode *p)//查找左子树结点 { return p->lchild; } BTNode *RchildNode(BTNode *p)//查找右子树结点 { return p->rchild; } int BiTreeDepth(BTNode *b)//求高度 { int lchilddep,rchilddep; if(b==NULL)return 0; else { lchilddep=BiTreeDepth(b->lchild); rchilddep=BiTreeDepth(b->rchild); return (lchilddep>rchilddep)?(lchilddep+1):(rchilddep+1); } } void DispBiTree(BTNode *b)//输出二叉树 { if(b!=NULL) { printf("%c",b->data); if(b->lchild!=NULL||b->rchild!=NULL) { printf("("); DispBiTree(b->lchild); if(b->rchild!=NULL) { printf(","); DispBiTree(b->rchild); } printf(")"); } } } void DispBTNode1(BTNode *b)//以凹入表示法输出一颗二叉树 { BTNode *St[MaxSize],*p; int level[MaxSize][2],top=-1,n,i,width=4; char type; if(b!=NULL) { top++; St[top]=b;//根结点入栈 level[top][0]=width; level[top][1]=2;//2表示是根 while(top>-1) { p=St[top];//退桟并凹入显示该结点值 n=level[top][0]; switch(level[top][1]) { case 0:type='L';break;//左结点之后输出(L) case 1:type='R';break;//右结点之后输出(R) case 2:type='B';break;//根结点之后输出(B) } for(i=1;i<=n;i++)//其中n为显示场宽,字符以右对齐显示 printf(" "); printf("%c(%c)",p->data,type); for(i=n+1;i<=MaxWidth;i+=2) printf("--"); printf("\n"); top--; if(p->rchild!=NULL) { top++;//将右子树根结点入栈 St[top]=p->rchild; level[top][0]=n+width;//显示场宽增width level[top][1]=1;//1表示是右子树 } if(p->lchild!=NULL) { top++;//将左子树根结点入栈 St[top]=p->lchild; level[top][0]=n+width;//显示场宽增width level[top][1]=0;//0表示是左子树 } } } } void PreOrder(BTNode *p)//先序遍历二叉树 { if(p!=NULL) { printf("%c",p->data); PreOrder(p->lchild); PreOrder(p->rchild); } } void PreOrder1(BTNode *b)//先序遍历的非递归算法 { BTNode *St[MaxSize],*p; int top=-1; if(b!=NULL) { top++;//根结点入栈 St[top]=b; while(top>-1)//桟不为空时循环 { p=St[top];//退桟并访问该结点 top--; printf(" %c ",p->data); if(p->rchild!=NULL)//右孩子入桟 { top++; St[top]=p->rchild; } if(p->lchild!=NULL)//左孩子入桟 { top++; St[top]=p->lchild; } } printf("\n"); } } void InOrder(BTNode *p)//中序遍历二叉树 { if(p!=NULL) { InOrder(p->lchild); printf("%c",p->data); InOrder(p->rchild); } } void InOrder1(BTNode *b)//中序遍历的非递归算法 { BTNode *St[MaxSize],*p; int top=-1; if(b!=NULL) { p=b; while(top>-1||p!=NULL) { while(p!=NULL) { top++; St[top]=p; p=p->lchild; } if(top>-1) { p=St[top]; top--; printf(" %c ",p->data); p=p->rchild; } } printf("\n"); } } void PostOrder(BTNode *p)//后序遍历二叉树 { if(p!=NULL) { PostOrder(p->lchild); PostOrder(p->rchild); printf("%c",p->data); } } void PostOrder1(BTNode *b)//后序遍历的非递归算法 { BTNode *St[MaxSize],*p; int flag,top=-1;//桟指针初值 if(b!=NULL) { do { while(b!=NULL)//将b的所有左结点入桟 { top++; St[top]=b; b=b->lchild; } p=NULL;//p指向当前结点的前一个访问的结点 flag=1;//设置b的访问标记为已访问过 while(top!=-1&&flag) { b=St[top];//取出当前的桟顶元素 if(b->rchild==p)//右子树不存在或已被访问,访问之 { printf(" %c ",b->data);//访问*b结点 top--; p=b;//p指向刚被访问的结点 } else { b=b->rchild;//指向右子树 flag=0;//设置未被访问的标记 } } }while(top!=-1); printf("\n"); } } void TravLevel(BTNode *b)//层次遍历 { BTNode *Qu[MaxSize];//定义顺序循环队列 int front,rear;//定义队首和队尾指针 front=rear=0;//置队列为空队列 if(b!=NULL) printf(" %c ",b->data); rear++;//结点指针进入队列 Qu[rear]=b; while(rear!=front)//队列不为空 { front=(front+1)%MaxSize; b=Qu[front]; if(b->lchild!=NULL)//队头出队列 { printf(" %c ",b->lchild->data);//输出左孩子,并入队列 rear=(rear+1)%MaxSize; Qu[rear]=b->lchild; } if(b->rchild!=NULL)//输出右孩子,并入队列 { printf(" %c ",b->rchild->data); rear=(rear+1)%MaxSize; Qu[rear]=b->rchild; } } printf("\n"); } void InTongji(BTNode *t,int &m,int &n)//中序遍历的方法求叶子结点的个数 { if(t!=NULL) { InTongji(t->lchild,m,n); printf("%c",t->data); m++;//结点计数 if((t->lchild==NULL)&&(t->rchild==NULL)) n++;//叶子结点计数 InTongji(t->rchild,m,n); } } int CountLeaf(BTNode *T)//返回二叉树所有叶子结点个数 { int m,n; if(!T)return 0; if(!T->lchild&&!T->rchild)return 1; else { m=CountLeaf(T->lchild); n=CountLeaf(T->rchild); return m+n; } } int Count(BTNode *T)//返回二叉树所有结点个数 { int m,n; if(!T) return 0; //if(!T->lchild&&!T->rchild)return 1; else { m=Count(T->lchild); n=Count(T->rchild); return m+n+1; } } BTNode *GetTreeNode(char item,BTNode*lptr,BTNode *rptr) //其数据域为item,左指针域为lptr,右指针域为rptr { BTNode *T; T=new BTNode; T->data=item; T->lchild=lptr; T->rchild=rptr; return T; } BTNode *CopyTree(BTNode *T) { BTNode *newlptr,*newrptr,*newT; if(!T)return NULL; if(T->lchild) newlptr=CopyTree(T->lchild);//复制左子树 else newlptr=NULL; if(T->rchild) newrptr=CopyTree(T->rchild); else newrptr=NULL; newT=GetTreeNode(T->data,newlptr,newrptr);//复制右子树 return newT; } BTNode*DestoryTree(BTNode *&T) { if(T==NULL)return 0; DestoryTree(T->lchild); DestoryTree(T->rchild); delete(T); T=NULL; return 0; } void output() { int i; for(i=0;i<10;i++) printf(" "); for(i=0;i<32;i++) printf("*"); printf("\n"); } void mainpp() { int i; output(); for(i=0;i<10;i++)printf(" ");printf("* "); printf("1.构建一颗二叉树"); for(i=0;i<10;i++)printf(" ");printf("*");printf("\n"); for(i=0;i<10;i++)printf(" ");printf("* "); printf("2.先序输出二叉树"); for(i=0;i<10;i++)printf(" ");printf("*");printf("\n"); for(i=0;i<10;i++)printf(" ");printf("* "); printf("3.中序输出二叉树"); for(i=0;i<10;i++)printf(" ");printf("*");printf("\n"); for(i=0;i<10;i++)printf(" ");printf("* "); printf("4.后序输出二叉树"); for(i=0;i<10;i++)printf(" ");printf("*");printf("\n"); for(i=0;i<10;i++)printf(" ");printf("* "); printf("5.层序输出二叉树"); for(i=0;i<10;i++)printf(" ");printf("*");printf("\n"); for(i=0;i<10;i++)printf(" ");printf("* "); printf("6.求二叉树的高度"); for(i=0;i<10;i++)printf(" ");printf("*");printf("\n"); for(i=0;i<10;i++)printf(" ");printf("* "); printf("7.输出二叉树叶结点"); for(i=0;i<8;i++)printf(" ");printf("*");printf("\n"); for(i=0;i<10;i++)printf(" ");printf("* "); printf("8.以括号形式输出所有结点"); for(i=0;i<2;i++)printf(" ");printf("*");printf("\n"); for(i=0;i<10;i++)printf(" ");printf("* "); printf("9.输出二叉树所有结点总数"); for(i=0;i<2;i++)printf(" ");printf("*");printf("\n"); for(i=0;i<10;i++)printf(" ");printf("* "); printf("10.删除二叉树"); for(i=0;i<13;i++)printf(" ");printf("*");printf("\n"); for(i=0;i<10;i++)printf(" ");printf("* "); printf("0.退 出"); for(i=0;i<8;i++)printf(" ");printf("*");printf("\n"); output(); } int main() { int m=0,n=0,k=1,t; BTNode*root=NULL; mainpp(); t=0; while(k) { printf("请选择0--10: "); scanf("%d",&m); getchar(); switch(m) { case 0:return 0; case 1:printf("输入字符,构建二叉树:\n");createbitree(root);break; case 2:printf("先序输出二叉树各结点:\n"); printf("递归算法:\n");PreOrder(root);printf("\n"); printf("非递归算法:\n");PreOrder1(root);printf("\n");break; case 3:printf("中序输出二叉树各结点: "); printf("递归算法:\n");InOrder(root);printf("\n"); printf("非递归算法:\n");InOrder1(root);printf("\n");break; case 4:printf("后序输出二叉树各结点: "); printf("递归算法:\n");PostOrder(root);printf("\n"); printf("非递归算法:\n");PostOrder1(root);printf("\n");break; case 5:printf("层序输出二叉树各结点:\n"); TravLevel(root);printf("\n");break; case 6:t=BiTreeDepth(root);printf("二叉树的高度=%3d\n",t);break; case 7:printf("输出一颗给定二叉树的所有叶子结点:"); DispLeaf(root); n=CountLeaf(root);printf("\n叶子结点总数: n=%3d\n",n);break; case 8:printf("以嵌套形式输出所有结点:\n"); DispBiTree(root); printf("\n"); break; case 9:printf("输出二叉树所有结点总数%3d\n",Count(root)); break; case 10:printf("删除二叉树结点"); DestoryTree(root); break; default:return 0; } printf("继续运行吗Y(1)/N(0): "); scanf("%d",&k); if(!k)return 0; } return 0; }