实验报告实验题目:二叉树实验目的:1、熟悉二叉树的结点类型和二叉树的基本操作。
2、掌握二叉树的前序、中序和后序遍历的算法。
3、加深对二叉树的理解,逐步培养解决实际问题的编程能力。
基本要求:1.编写程序bitree.cpp实现ADTBiTree,要求使用二叉链表存储。
实现基本操作:InitBiTree(&T);DestroyBiTree(&T);PreOrder(T,visit());InOrder(T,visit());PostOrder(T,visit());2.编码实现以下算法:1)创建二叉树。
(以先序扩展序列给出)2)输出先序、中序和后序序列。
3)计算二叉树结点数、叶子结点数、高度。
测试数据:先序扩展序列:ABDF##G##E#H##C##输出:先序ABDFGEHC中序FDGBEHAC后序FGDHEBCA结点数:8叶子结点数:4高度:4。
实验拓展1)实现层次遍历。
2)查找:查值为X的结点、双亲结点、孩子结点、兄弟结点3)判断:判断一个二叉树是否为二叉排序树、完全二叉树、平衡和二叉树4)处理:左右子树互换、复制、删除子树、插入子树设计思路:1.在二叉树的存储结构为链式存储结构。
2.在具体实现的时候建立不同函数,在主程序中用循环菜单的形式调用函数提高了效率。
概要分析:二叉链表结构定义:typedef struct BiNode{ElemType data;struct BiNode *lchild,*rchild;}BiNode,*BiTree;CreatBiTree(BiTree &T);先序建立二叉树。
DestroyBiTree(BiTree &T);销毁二叉树;PreOrder(BiTree &T);先序遍历二叉树InOrder(BiTree &T);中序遍历二叉树PostOrder (BiTree &T);后序遍历二叉树PrintbyLev(BiTree &T);按层次遍历二叉树,利用队列的思想,从根结点开始将其放入一个数组中,用i记录子节点尚未放入数组的位置,再将i所指向节点的左右节点放入队列中,然后i+1,对下一个节点这样操作,直至最后一个节点是叶子节点。
IsLeaf(BiTree &T);判断是否为叶子节点(是否有左右子树)。
FullBiTree(BiTree &T);判断是否为完全二叉树,采用广度优先遍历,从根节点开始,入队列,如果队列不为空,循环。
遇到第一个没有左儿子或者右儿子的节点,设置标志位,如果之后再遇到有左/右儿子的节点,那么这不是一颗完全二叉树。
CountBiTree(BiTree &T);节点计数,用递归思想,对左右子树计数,再加起来。
LevelNum(BiTree& T,int t,int d);计算层数,利用递归思想,对左右子树计算层数并取较大值。
LeafNum(BiTree& T,int t,int d,int ln);叶子节点计数,利用递归思想,计算左右子树叶子再计算和。
Balance(BiTree &T,int i);判断是否为平衡二叉树,递归判断左右是否为平衡二叉树(有层数记录)。
Sort(BiTree &T,int i);判断是否为二叉排序树,判断此节点是否满足排序树定义,在判断其左右子树是否满足。
PrintChild(BiTree &T);打印左右子树。
FindNode(ElemType x,BiTree &T);查找算法,如果是根节点提示是根节点并返回指向根节点的指针,若果不是则调用Findx函数。
FindX(ElemType x,BiTree &temp,BiTree &T);查找算法,返回指向对应子树的根节点的指针。
CopyBiT(BiTree &T,BiTree &C);复制子树。
运行截图:主界面建立二叉树输出三序遍历及二叉树信息按层输出查找二叉树分析二叉树左右子树互换:对A 然后按层次输出删除以B为根节点的子树:(层次遍历)复制节点C增加节点B于A的左节点(层次遍历)结果与讨论:程序完成情况较好,由于实验内容比较多,所以写了很多函数,但有些函数之间是有调用关系,减轻了工作量。
同时利用循环菜单也让程序看起来更为简洁,调用子程序也更为方便。
程序代码:#include <iostream>#include <stdio.h>#include <stdlib.h>#include <math.h>using namespace std;typedef int Status;typedef char ElemType; typedef struct BiNode{ElemType data;struct BiNode *lchild,*rchild; }BiNode,*BiTree;#define OK 1#define ERROR 0//先序遍历建立二叉树Status CreatBiTree(BiTree &T){ ElemType c;cin >> c;if(c=='.'){T=NULL;}else{T=(BiNode*)malloc(sizeof(BiNode));T->data=c;CreatBiTree(T->lchild);CreatBiTree(T->rchild);}return 1;}Status DestroyBiTree(BiTree &T){if(!T) return 1;else{DestroyBiTree(T->lchild);DestroyBiTree(T->rchild);free(T);T=NULL;return 1;}}Status PreOrder(BiTree &T){if(T){printf("%c",T->data);if(PreOrder(T->lchild))if(PreOrder(T->rchild)) return 1;return 0;}else return 1;}Status InOrder(BiTree &T){if(T){InOrder(T->lchild);printf("%c",T->data);InOrder(T->rchild);return 1;}else return 1;}Status PostOrder(BiTree &T){if(T){PostOrder(T->lchild);PostOrder(T->rchild);printf("%c",T->data);return 1;}//按层输出Status PrintbyLev(BiTree &T){int i=0;BiTree node[100];int nn=1;for(i=0;i<100;i++) node[i]=NULL;node[0]=T;i=0;while(node[i]){if(node[i]->lchild){node[nn]=node[i]->lchild;nn++;}if(node[i]->rchild){node[nn]=node[i]->rchild;nn++;}i++;//CreatQueue(T);for(i=0;node[i];i++){printf("%c",node[i]->data);}printf("\n");return 1;}int IsLeaf(BiTree &T){if(T->lchild==NULL&&T->rchild==NULL) return 1;//叶子节点else if(!T->lchild&&T->rchild) return 2;//有右无左else if(!T->rchild&&T->lchild) return 3;//有左无右else return 0; //有左有右}Status FullBiTree(BiTree &T){int i=0,j=0;BiTree node[100];int nn=1;for(i=0;i<100;i++) node[i]=NULL; node[0]=T;i=0;while(node[i]){if(node[i]->lchild){node[nn]=node[i]->lchild;nn++;}if(node[i]->rchild){node[nn]=node[i]->rchild;nn++;}i++;}i=0;while(node[i]){if(IsLeaf(node[i])==2) return 0;i++;}while(IsLeaf(node[j])==0){j++;printf("*");}//j++;指针停在非左右子树都存在的节点的下一位if(IsLeaf(node[j])==3||IsLeaf(node[j])==1) j++;while(node[j]!=NULL){if(IsLeaf(node[j])!=1) return 0;j++;printf("*");}return 1;}//计数int CountBiTree(BiTree &T){int m,n;if(T){m=CountBiTree(T->lchild);n=CountBiTree(T->rchild );return m+n+1;else return 0;}//层数int LevelNum(BiTree& T,int t,int d){ if(t>d) d=t;if(!T) return 0;if (T->lchild) {d=LevelNum(T->lchild,t+1,d);}if (T->rchild) {d=LevelNum(T->rchild,t+1,d);}return d;}//叶子节点计数int LeafNum(BiTree& T,int t,int d,int ln){ if(t==d) ln++;if(!T) return 0;if (T->lchild) {ln=LevelNum(T->lchild,t+1,ln);if (T->rchild) {ln=LevelNum(T->rchild,t+1,ln);}return ln;}//判断平衡int Balance(BiTree &T,int i){if (i==0) return i;if (!T) return i;if (abs(CountBiTree(T->lchild)-CountBiTree(T->rchild))>1){ i=0;return 0;}else {Balance(T->lchild,i);Balance(T->rchild,i);}return i;}//判断二叉排序树int Sort(BiTree &T,int i){if (i==0) return 0;if(!T) return i;if(T->lchild){if (T->data<T->lchild->data) return 0;i=Sort(T->lchild,i);}else if (T->rchild){if (T->data<T->rchild->data) return 0;i=Sort(T->rchild,i);}return i;}void judge(BiTree &T){if(FullBiTree(T))printf("是完全二叉树\n");if(Balance(T,1))printf("是平衡二叉树\n");if(Sort(T,1))printf("是二叉排序树\n");}//打印子树void PrintChild(BiTree &T){if(!T->lchild) printf("此节点无左子树\n");else printf("左子树为:%c\n",T->lchild->data);if(!T->rchild) printf("此节点无右子树\n");else printf("右子树为:%c\n",T->rchild->data); }BiTree FindX(ElemType x,BiTree &temp,BiTree &T){ if (temp!=NULL||T==NULL) return temp;if (T->lchild){if (T->lchild->data==x)return T;else {temp=FindX(x,temp,T->lchild);temp=FindX(x,temp,T->rchild);if(temp) return temp;}}if (T->rchild){//printf("**");if (T->rchild->data==x)return T;else {temp=FindX(x,temp,T->rchild);temp=FindX(x,temp,T->lchild);if(temp) return temp;}}return temp;}//找X节点BiTree FindNode(ElemType x,BiTree &T){if(T->data==x){printf("所找节点为根节点\n");PrintChild(T);return T;}BiTree Q=NULL;Q=FindX(x,Q,T);if(Q){printf("其双亲节点为:%c\n",Q->data);if(Q->lchild&&Q->lchild->data==x) {if (!Q->rchild) printf("其无兄弟节点\n");else printf("兄弟节点为%c\n",Q->rchild->data);PrintChild(Q->lchild);//return Q->lchild;}else{if (!Q->lchild) printf("其无兄弟节点\n");else printf("兄弟节点为%c\n",Q->lchild->data);PrintChild(Q->rchild);//return Q->rchild;}}return Q;}//三序输出void printBiTree(BiTree &T){int d,Ln,n;PreOrder(T);printf("\n");InOrder(T);printf("\n");PostOrder(T);printf("\n");n=CountBiTree(T);printf("节点数为:%d\n",n);d=LevelNum(T,1,1);printf("深度为:%d\n",d);Ln=LeafNum(T,1,d,0);printf("叶子节点个数为:%d\n",Ln); }Status CopyBiT(BiTree &T,BiTree &C){if(!T) C=NULL;else{C=(BiNode*)malloc(sizeof(BiNode));C->data=T->data;//C->lchild=T->lchild;//C->rchild=T->rchild;CopyBiT(T->lchild,C->lchild);CopyBiT(T->rchild,C->rchild);}return 1;}int main(){BiTree T,x,temp,temp1;int d,Ln,n,j=1;ElemType c;while(j){printf("1.建立二叉树\n");printf("2.前中后序输出二叉树\n");printf("3.按层输出二叉树\n");printf("4.查找二叉树\n");printf("5.分析二叉树\n");printf("6.左右子树互换\n");printf("7.删除子树\n");printf("8.复制子树\n");printf("9.增加子树\n");scanf("%d",&j);switch(j){case 1: CreatBiTree(T);break;case 2: printBiTree(T);break;case 3: PrintbyLev(T); break;case 4:printf("请输入要查询节点:\n");getchar();scanf("%c",&c);x=FindNode(c,T);break;case 5:judge(T);break;case 6:printf("输入根节点:\n");getchar();scanf("%c",&c);if(c==T->data){x=T;temp=x->lchild;x->lchild=x->rchild;x->rchild=temp;PrintChild(T);break;}x=FindNode(c,T);if(x->lchild&&x->lchild->data==c){ x=x->lchild;//x->lchild=NULL;}else if(x->rchild&&x->rchild->data==c) { x=x->rchild;// x->rchild=NULL;}temp=x->lchild;x->lchild=x->rchild;x->rchild=temp;printf("交换之后:\n");PrintChild(x);break;case 7:printf("输入根节点:\n");getchar();scanf("%c",&c);if(T->data==c){x=T;}else{x=FindNode(c,T);}if(x->lchild&&x->lchild->data==c){temp=x->lchild;x->lchild=NULL;}else if(x->rchild&&x->rchild->data==c) { temp=x->rchild;x->rchild=NULL;}//printBiTree(x);DestroyBiTree(temp);break;//x=NULL;case 8:printf("输入根节点:\n");getchar();scanf("%c",&c);x=FindNode(c,T);if(x->lchild&&x->lchild->data==c){temp=x->lchild;}else if(x->rchild&&x->rchild->data==c) { temp=x->rchild;// x->rchild=NULL;}CopyBiT(temp,temp1);printBiTree(temp1);break;case 9:printf("输入要插入的子树:\n");CreatBiTree(temp1);printf("输入插入根节点:\n");getchar();scanf("%c",&c);if(T->data==c){temp=T;}else{x=FindNode(c,T);if(x->lchild&&x->lchild->data==c){temp=x->lchild;}else if(x->rchild&&x->rchild->data==c) { temp=x->rchild;}}printf("1.左子树2.右子树\n");scanf("%d",&d);if(d==1) temp->lchild=temp1;else temp->rchild=temp1;//printBiTree(T);}}}。