1、if(ch=0) *t=NULL;else*t=(Binnode*)malloc(sizeof(Binnode);if(!*t)exit(OVERFLOW);(*t)-data=ch;printf(%c: left,ch); Creat_Bintree(&lchild); rightCreat_Bintree(&rchild);/*按照前序递归遍历二叉树*/void Preorder1(Binnode *t)if(t!=NULL)%c,t-data);Preorder1(t-/*按照中序递归遍历二叉树*/void Inorder1(Binnode *t) /* printf(n输出中序递归遍历
2、序列:);*/Inorder1(t-/* 按照后序递归遍历二叉树*/void Posorder1(Binnode *t)n输出后序递归遍历序列:Posorder1(t-/*按照前序非递归遍历二叉树*/void preorder2(Binnode *root)/*先序非递归遍历二叉树*/ Binnode *p,*stack100;int top ;p=root;if(root!top=1;stacktop=p;while(top0)p=stacktop ;/*将右小孩放入栈*/top-;,p-if(p-rchild!top+;stacktop=p-rchild;lchild!lchild;/*按
3、照中序非递归遍历二叉树*/void Inorder2(Binnode *root)/*中序非递归遍历二叉树*/int top=0;dowhile(p!top+;p=p-if(topp=stacktop;/*p所指的节点为无左子树或其左子树已经遍历过*/while(p!=NULL|top!=0);/*按照后序非递归遍历二叉树*/void Posorder2(Binnode *t)Binnode *s100;int top=-1;int flag100;while(t!=-1)while(t)flagtop=0;stop=t;t=t-=0&flagtop=1)t=stop;=0)flagtop=1
4、;t=NULL;/*按照层次遍历二叉树*/int front=0,rear=1;void Levelorder(Binnode *t)Binnode *q100;q0=t;/* int front=0,rear=1;while(frontqrear+=qfront-front+;/*递归法将二叉树的左右子树互换*/void Exchange1(Binnode *t)Binnode *temp;if(t)Exchange1(t-temp=t-t-lchild=t-rchild=temp;/*非递归法将二叉树的左右子树互换*/void Exchange2(Binnode *t)while(t|to
5、p)stop+=t;t=s-top-/*递归法求叶子结点个数*/int Leaves_Num1(Binnode *t)if(t-lchild=NULL&rchild=NULL)return 1;return (Leaves_Num1(t-lchild)+Leaves_Num1(t-rchild);else return 0;/*非递归法求叶子结点个数*/int Leaves_Num2(Binnode *t)int count=0,top=0;while(t|topcount+;/*输出叶子结点*/return count;int main()Binnode *proot=NULL;int p,
6、q;1.CreateBitree:nproot); /*建立二叉树时,无左右孩子的结点输入0值*/n2.Output Digui PreOrder:Preorder1(proot);n3.Output Not Digui PreOrder:preorder2(proot);n4.Output Digui InOrder:Inorder1(proot);n5.Output Not Digui InOrder:Inorder2(proot);n6.Output Digui PostOrder:Posorder1(proot);n7.Output Not Digui PostOrder:Posord
7、er2(proot);n8.Output LevelOrde:Levelorder(proot);Exchange1(proot);n9.Output Digui Exchange:Exchange2(proot);n10.Output Not Digui Exchange:n11.Leaves_Node:q=Leaves_Num2(proot);n12.Output Not Digui Leaves_Num:%dn,q);p=Leaves_Num1(proot);13.Output Digui Leaves_Num:,p);nThis System Once Againnreturn 0;【
8、思考题】【调试说明】(1)建立二叉树时,必须按先序遍历方式依次输入结点值(该程序中为字符)。当输入叶子结点时,它的左右子树为空以输入“0”值作为结束。(2)该程序集中了二叉树操作的常用算法,根据需要可以在此基础上进行裁剪,只实现其中一种即可,并调试运行。当用二叉链表作为二叉树的存储结构时,因为每个结点中只有指向其左、右孩子结点的指针,所以从任一结点出发只能直接找到该结点的左、右孩子。在一般情况下靠它无法直接找到该结点在某种遍历次序下的前驱和后继结点。如果在每个结点中增加指向其前驱和后继结点的指针,将降低存储空间的效率。与此同时,我们可以证明:在n个结点的二叉链表中含有n+1个空指针。因为含n个
9、结点的二叉链表中含有2n个指针,除了根结点,每个结点都有一个从父结点指向该结点的指针,因此一共使用了n-1个指针,所以在n个结点的二叉链表中含有2n-(n-1)=n+1个空指针。因此,可以利用这些空指针,存放指向结点在某种遍历次序下的前驱和后继结点的指针。这种附加的指针称为线索,加上了线索的二叉链表称为线索链表,相应的二叉树称为线索二叉树。为了区分一个结点的指针是指向其孩子的指针,还是指向其前驱或后继结点的线索,可在每个结点中增加两个线索标志。这样,线索二叉树结点类型定义为:LchildLtagDataRtagRchild其中:1. Ltag=0时,表示Lchild指向该结点的左孩子;2. L
10、tag=1时,表示Lchild指向该结点的线性前驱结点;3. Rtag=0时,表示Rchild指向该结点的右孩子;4. Rtag=1时,表示Rchild指向该结点的线性后继结点;以二叉链表结点数据结构所构成的二叉链表作为二叉树的存储结构,叫做线索二叉链表;指向结点的线性前驱或者线性后继结点的指针叫做线索;加上线索的二叉树称为线索二叉树;对二叉树以某种次序遍历将其变为线索二叉树的过程叫做线索化。中序线索化是指用二叉链表结点数据结构建立二叉树的二叉链表,然后按照中序遍历的方法访问结点时建立线索。 例如有如上图所示二叉树,则中序遍历的顺序是:O / J * I + H A G【参考程序】typede
11、f enumLink,Thread PointerTag; /*指针标志*/ typedef char DataType;typedef struct BiThreTree /*定义结点元素*/ PointerTag LTag,RTag;DataType data;struct BiThreTree *lchild,*rchild;BiThreTree;BiThreTree *pre; /*全局变量,用于二叉树的线索化*/ BiThreTree *CreateTree() /*按前序输入建立二叉树*/ BiThreTree *T;DataType ch;if(ch=#) T=NULL;else
12、 T=(BiThreTree *)malloc(sizeof(BiThreTree);T-LTag=Link; /*初始化时指针标志均为Link*/ RTag=Link;lchild=CreateTree();rchild=CreateTree(); return T;void InThread(BiThreTree *T) BiThreTree *p;p=T;if(p) InThread(p-p-lchild) p-LTag=Thread;lchild=pre;pre-rchild) pre-RTag=Thread;rchild=p;pre=p;BiThreTree *InOrderThrT
13、ree(BiThreTree *T) /*中序线索化二叉树*/ BiThreTree *Thre; /*Thre为头结点的指针*/ Thre=(BiThreTree *)malloc(sizeof(BiThreTree);Thre-lchild=T;rchild=Thre;pre=Thre;InThread(T);rchild=pre;return Thre;void InThrTravel(BiThreTree *Thre) /*中序遍历二叉树*/ p=Thre-=Thre) /*指针回指向头结点时结束*/ while(p-LTag=Link) %4cRTag=Thread&=Thre) p
14、=p-void main() BiThreTree *T,*Thre;printf(“PreOrder Create Binary Tree:n”);T=CreateTree();Thre=InOrderThrTree(T);printf(“InOrder Traverse Binary Tree:InThrTravel(Thre);system(pause【调试举例】(1)建立二叉树时,按先序遍历方式输入:“ABD#EH#I#CF#G#”,其中“#”表示空指针。(2)建立的二叉树为: AB CD E F GH I (3)程序输出为中序遍历线索化二叉树的结果:DBHEIAFCG已知A、B和C为
15、三个递增有序的线性表,现要求对A表作如下操作:删除那些既在B表中出现又在C表中出现的元素。1.试对顺序表编写实现上述操作的算法并上机编写代码,要求算法尽可能高效。在实验报告中分析你的算法的时间复杂度。2.A表中要删除的元素实际上就是在三个表中都存在的元素。注意这三个线性表都是递增有序的线性表!可以利用这一性质减少对线性表“扫描”的趟数。3.改用单链表作为存储结构编写算法,请释放A表中无用的结点空间,并上机编程实现。【算法思想】先从B和C中找出共有元素same,再从A中从当前位置开始,凡小于same的元素均保留,等于same的就跳过,大于same时就再找下一个same。【顺序存储结构算法描述】v
16、oid SqList_Delete(SqList&A, SqList B, SqList C)i=0;j=0;m=0;/*i指示A中元素原来的位置,m为移动后的位置*/while(iA.length&jB.length&kC.length)if(B.elemjC.elemk)k+;elsesame= B.elemj;/*找到了相同元素same*/while(B.elemj=same)j+;while(C.elemk)=same)k+;/*j,k后移到新的元素*/A.elemisame)A.elemm+=A.elemi+;/*需要保留的元素移动到新位置*/while( iA.elemi=same
17、)i+;/*else*/*while*/A.length)/*A的剩余元素重新存储*/A.length=m;/*SqList_Delete*/【顺序存储结构参考程序】#includemain()#define N 3/*宏定义,代表数组维数*/#define M 4#define T 5int i,j,k,r,m,same;/*定义变量分别指向数组a,b,c*/int aN,bM,cT;printf(“please input numbers:for (i=0;iN;i+) scanf(%dai);for (j=0;M;j+) scanf(bj);for (k=0;T;k+) scanf(ck
18、);k=0;/*分别赋值为0,即指向数组的第一元素*/N&M&T)if(bjck) k+;same=bj;while(bj=same)j+;while(ck=same)k+;aiam+=ai+;ai=same) i+;N)a%d=,m);/*输出删除元素后的数组a/*for (r=0;rm-1;r+)printf(%d,ar);,am-1);nreturn;【程序调试】程序运行是屏幕显示:please input numbers: 此时输入三组测试数据,数据间用空格隔开:2 3 4回车3 4 5 6 回车4 5 6 7 8 回车 程序输出结果:a3=2,3,即删除了数组a中即在b和c中都出现的
19、元素。【单链表存储结构参考程序】# include Typedef struct LNodeint data;struct LNode *next;Lnode,*LinkList;/*定义链表节点的结构*/void main ( )/*功能:建立单链表A,B,C,并且删除A中均在B和C中出现的数据。CreateList (LinkList head);/*函数声明*/ListDelete (LinkList La, LinkList Lb ,LinkList Lc);Print (LinkList head);LinkList headA,headB,headC;headA=NULL;head
20、B=NULL;headC=NULL;headA=CreateList(headA);/*建立链表*/headB=CreateList(headB);headC=CreateList(headC);print(headA);/*输出显示链表数据*/print(headB);print(headC);headA=ListDelete(headA,headB,headC);/*删除A中满足条件的节点*/Print (headA);LinkList createList(LinkList head)建立有头节点head的数据单链表*/LinkList p,q;p=q=(LinkList)malloc(sizeof(Ln
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1