1、/Bitree_Sim 6.37 void PreOrder_Nonrecursive(Bitree T)/先序遍历二叉树的非递归算法InitStack(S);Push(S,T); /根指针进栈while(!StackEmpty(S)while(Gettop(S,p)&p)visit(p-data);push(S,p-lchild); /向左走到尽头pop(S,p); pop(S,p); push(S,p-rchild); /向右一步/while/PreOrder_Nonrecursive 6.38 typedef struct BTNode* ptr; enum 0,1,2 mark; PM
2、Type; /有mark域的结点指针类型 void PostOrder_Stack(BiTree T)/后续遍历二叉树的非递归算法,用栈PMType a; /S的元素为PMType类型Push (S,T,0); /根结点入栈Pop(S,a);switch(a.mark)case 0:Push(S,a.ptr,1); /修改mark域if(a.ptr-lchild) Push(S,a.ptr-lchild,0); /访问左子树break;case 1:Push(S,a.ptr,2);rchild) Push(S,a.ptr-rchild,0); /访问右子树case 2:visit(a.ptr)
3、; /访问结点,返回/PostOrder_Stack分析:为了区分两次过栈的不同处理方式,在堆栈中增加一个mark域,mark=0表示刚刚访问此结点,mark=1表示左子树处理结束返回,mark=2表示右子树处理结束返回.每次根据栈顶元素的mark域值决定做何种动作. 6.39 int data; EBTNode *lchild; EBTNode *rchild; EBTNode *parent; EBTNode,EBitree; /有mark域和双亲指针域的二叉树结点类型 void PostOrder_Nonrecursive(EBitree T)/后序遍历二叉树的非递归算法,不用栈p=T;
4、while(p)switch(p-mark)p-mark=1;if(p-lchild) p=p-lchild;mark=2;rchild) p=p-rchild;visit(p);mark=0; /恢复mark值p=p-parent; /返回双亲结点/PostOrder_Nonrecursive本题思路与上一题完全相同,只不过结点的mark值是储存在结点中的,而不是暂存在堆栈中,所以访问完毕后要将mark域恢复为0,以备下一次遍历. 6.40 PBTNode *lchild; PBTNode *rchild; PBTNode *parent; PBTNode,PBitree; /有双亲指针域的
5、二叉树结点类型 void Inorder_Nonrecursive(PBitree T)/不设栈非递归遍历有双亲指针的二叉树while(p- /向左走到尽头rchild) /寻找中序后继:当有右子树时 /后继就是在右子树中向左走到尽头else if(p-parent-lchild=p) p=p- /当自己是双亲的左孩子时后继就是双亲parent&rchild=p) p=p- /当自己是双亲的右孩子时后继就是向上返回直到遇到自己是在其左子树中的祖先/Inorder_Nonrecursive 6.41 int c,k; /这里把k和计数器c作为全局变量处理 void Get_PreSeq(Bitr
6、ee T)/求先序序列为k的结点的值if(T)c+; /每访问一个子树的根都会使前序序号计数器加1if(c=k)printf(Value is %dn,T-exit (1);Get_PreSeq(T- /在左子树中查找 /在右子树中查找/if/Get_PreSeq main().scanf(%d,&k);c=0; /在主函数中调用前,要给计数器赋初值0Get_PreSeq(T,k);/main 6.42 int LeafCount_BiTree(Bitree T)/求二叉树中叶子结点的数目T) return 0; /空树没有叶子else if(!T-lchild&rchild) return
7、1; /叶子结点else return Leaf_Count(T-lchild)+Leaf_Count(T-/左子树的叶子数加上右子树的叶子数/LeafCount_BiTree 6.43 void Bitree_Revolute(Bitree T)/交换所有结点的左右子树lchild /交换左右子树if(T-lchild) Bitree_Revolute(T-rchild) Bitree_Revolute(T- /左右子树再分别交换各自的左右子树/Bitree_Revolute 6.44 int Get_Sub_Depth(Bitree T,int x)/求二叉树中以值为x的结点为根的子树深度
8、data=x)%dn,Get_Depth(T); /找到了值为x的结点,求其深度exit 1;lchild) Get_Sub_Depth(T-lchild,x);rchild) Get_Sub_Depth(T-rchild,x); /在左右子树中继续寻找/Get_Sub_Depth int Get_Depth(Bitree T)/求子树深度的递归算法m=Get_Depth(T-n=Get_Depth(T-return (mn?m:n)+1;/Get_Depth 6.45 void Del_Sub_x(Bitree T,int x)/删除所有以元素x为根的子树data=x) Del_Sub(T)
9、; /删除该子树lchild) Del_Sub_x(T-rchild) Del_Sub_x(T- /在左右子树中继续查找/else/Del_Sub_x void Del_Sub(Bitree T)/删除子树Tlchild) Del_Sub(T-rchild) Del_Sub(T-free(T);/Del_Sub 6.46 void Bitree_Copy_Nonrecursive(Bitree T,Bitree &U)/非递归复制二叉树InitStack(S1);InitStack(S2);push(S1,T);U=(BTNode*)malloc(sizeof(BTNode);U-data=T
10、-data;q=U;push(S2,U);while(Gettop(S1,p)&q-lchild=(BTNode*)malloc(sizeof(BTNode);q=q-data=p-push(S1,p-push(S2,q);pop(S1,p);pop(S2,q);StackEmpty(S1) pop(S1,p); q-rchild=(BTNode*)malloc(sizeof(BTNode); q=q- push(S1,p- push(S2,q);/BiTree_Copy_Nonrecursive本题的算法系从6.37改写而来. 6.47 void LayerOrder(Bitree T)/层
11、序遍历二叉树InitQueue(Q); /建立工作队列EnQueue(Q,T);QueueEmpty(Q)DeQueue(Q,p);lchild) EnQueue(Q,p-rchild) EnQueue(Q,p-/LayerOrder 6.48 int found=FALSE; Bitree* Find_Near_Ancient(Bitree T,Bitree p,Bitree q)/求二叉树T中结点p和q的最近共同祖先Bitree pathp 100 ,pathq 100 /设立两个辅助数组暂存从根到p,q的路径Findpath(T,p,pathp,0);found=FALSE;Findpa
12、th(T,q,pathq,0); /求从根到p,q的路径放在pathp和pathq中for(i=0;pathpi=pathqi&pathpi;i+); /查找两条路径上最后一个相同结点return pathp-i;/Find_Near_Ancient void Findpath(Bitree T,Bitree p,Bitree path ,int i)/求从T到p路径的递归算法if(T=p)found=TRUE;return; /找到pathi=T; /当前结点存入路径lchild) Findpath(T-lchild,p,path,i+1); /在左子树中继续寻找rchild&found)
13、Findpath(T-rchild,p,path,i+1); /在右子树中继续寻找found) pathi=NULL; /回溯/Findpath 6.49 int IsFull_Bitree(Bitree T)/判断二叉树是否完全二叉树,是则返回1,否则返回0flag=0;p) flag=1;else if(flag) return 0;EnQueue(Q,p- /不管孩子是否为空,都入队列/IsFull_Bitree该问题可以通过层序遍历的方法来解决.与6.47相比,作了一个修改,不管当前结点是否有左右孩子,都入队列.这样当树为完全二叉树时,遍历时得到是一个连续的不包含空指针的序列.反之,则
14、序列中会含有空指针. 6.50 Status CreateBitree_Triplet(Bitree &T)/输入三元组建立二叉树if(getchar()!=) return ERROR;T=(BTNode*)malloc(sizeof(BTNode);data=getchar();getchar(); /滤去多余字符while(parent=getchar()!(child=getchar()&(side=getchar()while(QueueHead(Q)!=parent&QueueEmpty(Q) DeQueue(Q,e);if(QueueEmpty(Q) return ERROR;
15、/未按层序输入p=QueueHead(Q);q=(BTNode*)malloc(sizeof(BTNode);if(side=L) p-lchild=q;else if(side=Rrchild=q;else return ERROR; /格式不正确data=child;EnQueue(Q,q);return OK;/CreateBitree_Triplet 6.51 Status Print_Expression(Bitree T)/按标准形式输出以二叉树存储的表达式data是字母) printf(%celse if(T-data是操作符)lchild|!rchild) return ERR
16、OR; /格式错误lchild-data是操作符&data优先级低于T-data)();Print_Expression(T-lchild) return ERROR;) /注意在什么情况下要加括号rchild-rchild) return ERROR; /非法字符/Print_Expression 6.52 typedef structBTNode node;int layer; BTNRecord; /包含结点所在层次的记录类型 int FanMao(Bitree T)/求一棵二叉树的繁茂度int countd; /count数组存放每一层的结点数 /Q的元素为BTNRecord类型EnQ
17、ueue(Q,T,0);DeQueue(Q,r);countr.layer+;if(r.node-lchild) EnQueue(Q,r.node-lchild,r.layer+1);rchild) EnQueue(Q,r.node-rchild,r.layer+1); /利用层序遍历来统计各层的结点数h=r.layer; /最后一个队列元素所在层就是树的高度for(maxn=count0,i=1;counti;i+)if(countimaxn) maxn=counti; /求层最大结点数return h*maxn;/FanMao如果不允许使用辅助数组,就必须在遍历的同时求出层最大结点数,形式
18、上会复杂一些,你能写出来吗?6.53 int maxh;Status Printpath_MaxdepthS1(Bitree T)/求深度等于树高度减一的最靠左的结点Bitree pathd;maxh=Get_Depth(T); /Get_Depth函数见6.44if(maxhexit; /打印输出路径lchild) Find_h(T-lchild,h+1);rchild) Find_h(T-rchild,h+1);pathh=NULL;/Find_h 6.54 Status CreateBitree_SqList(Bitree &T,SqList sa)/根据顺序存储结构建立二叉链表Bitree ptrsa.last+1; /该数组储存与sa中各结点对应的树指针sa.las
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1