#include <stdio.h> #include <stdlib.h> #include <malloc.h> #define MAXSIZE 100 typedef char ElemType; typedef enum { Link,/*指向孩子结点*/Thread/*指向前驱或后继*/ } PointerTag; typedef struct Node { ElemType data; struct Node *lchild; struct Node *rchild; PointerTag ltag,rtag; }*BitThrTree,BitThrNode; BitThrTree pre; void CreateBitTree2(BitThrTree *T,char str[]);//创建搜索二叉树 void InThreading(BitThrTree p);//中序线索化二叉树 int InOrderThreading(BitThrTree *Thrt,BitThrTree T);//通过中序遍历二叉树T,使T中序线索化。Thrt是指向头结点的指针 int InOrderTraverse(BitThrTree T,int (*visit)(BitThrTree e));//中序遍历线索二叉树 int Print(BitThrTree T);//打印二叉树的结点和线索标志 BitThrNode* FindPoint(BitThrTree T,ElemType e);//在线索二叉树中查找结点为e的指针 BitThrNode* InOrderPre(BitThrNode *p);//中序前驱 BitThrNode* InOrderPost(BitThrNode *p);//中序后继 void DestroyBitTree(BitThrTree *T);//销毁二叉树 #include "LinkBiTree.h" void CreateBitTree2(BitThrTree *T,char str[])//创建搜索二叉树 { char ch; BitThrTree stack[MAXSIZE]; int top = -1; int flag,k; BitThrNode *p; *T = NULL,k = 0; ch = str[k]; while(ch != '\0') { switch(ch) { case '(': stack[++top] = p; flag = 1; break; case ')': top--; break; case ',': flag = 2; break; default: p = (BitThrTree)malloc(sizeof(BitThrNode)); p->data = ch; p->lchild = NULL; p->rchild = NULL; if(*T == NULL) { *T = p; } else { switch(flag) { case 1: stack[top]->lchild = p; break; case 2: stack[top]->rchild = p; break; } if(stack[top]->lchild) { stack[top]->ltag = Link; } if(stack[top]->rchild) { stack[top]->rtag = Link; } } } ch = str[++k]; } } void InThreading(BitThrTree p)//中序线索化二叉树 { if(p)//左子树线索化 { InThreading(p->lchild); if(!p->lchild)//前驱线索化 { p->ltag = Thread; p->lchild = pre; } if(!pre->rchild)//后继线索化 { pre->rtag = Thread; pre->rchild = p; } pre = p; InThreading(p->rchild);//右子树线索化 } } int InOrderThreading(BitThrTree *Thrt,BitThrTree T)//通过中序遍历二叉树T,使T中序线索化。Thrt是指向头结点的指针 { if(!(*Thrt = (BitThrTree)malloc(sizeof(BitThrNode)))) { exit(-1);//为头结点分配单元 } (*Thrt)->ltag = Link;//修改前驱线索标志 (*Thrt)->rtag = Thread;//修改后继线索标志 (*Thrt)->rchild = *Thrt;//将头结点的rchild指针指向自己 if(!T)//如果二叉树为空,则将lchild指针指向自己 { (*Thrt)->lchild = *Thrt; } else { (*Thrt)->lchild = T;//将头结点的左指针指向根结点 pre = *Thrt;//将pre指向已经线索化的结点 InThreading(T);//中序遍历进行中序线索化 /*将最后一个结点线索化*/ pre->rchild = *Thrt;//将最后一个结点的右指针指向头结点 pre->rtag = Thread;//修改最后一个结点的rtag标志域 (*Thrt)->rchild = pre;//将头结点的rchild指针指向最后一个结点 } return 1; } int InOrderTraverse(BitThrTree T,int (*visit)(BitThrTree e))//中序遍历线索二叉树 { BitThrTree p; p = T->lchild ;//p指向根结点 while(p != T)//空树或遍历结束时,p == T { while(p->ltag == Link) { p = p->lchild ; } if(!visit(p))//打印 { return 0; } while(p->rtag == Thread && p->rchild != T)//访问后继结点 { p = p->rchild ; visit(p); } p = p->rchild ; } return 1; } int Print(BitThrTree T)//打印二叉树的结点和线索标志 { static int k = 1; printf("%2d\t%s\t %2c\t %s\t\n",k++,T->ltag == 0 ? "Link":"Thread",T->data ,T->rtag == 1 ? "Thread":"Link"); return 1; } BitThrNode* FindPoint(BitThrTree T,ElemType e)//在线索二叉树中查找结点为e的指针 { BitThrTree p; p = T->lchild ; while(p != T) { while(p->ltag == Link) { p = p->lchild ; } if(p->data == e) { return p; } while(p->rtag == Thread && p->rchild != T) { p = p->rchild ; if(p->data == e) { return p; } } p = p->rchild ; } return NULL; } BitThrNode* InOrderPre(BitThrNode *p)//中序前驱 { if(p->ltag == Thread)//如果p的标志域ltag为线索,则p的左子树结点为前驱 { return p->lchild ; } else { pre = p->lchild ;//查找p的左孩子的最右下端结点 while(pre->rtag == Link)//右子树非空时,沿右链往下查找 { pre = pre->rchild ; } return pre;//pre就是最右下端结点 } } BitThrNode* InOrderPost(BitThrNode *p)//中序后继 { if(p->rtag == Thread)//如果p的标志域rtag为线索,则p的右子树结点为后驱 { return p->rchild ; } else { pre = p->rchild ;//查找p的右孩子的最左下端结点 while(pre->ltag == Link)//左子树非空时,沿左链往下查找 { pre = pre->lchild ; } return pre;//pre就是最左下端结点 } } void DestroyBitTree(BitThrTree *T)//销毁二叉树 { if(*T) { if(!(*T)->lchild) { DestroyBitTree(&((*T)->lchild)); } if(!(*T)->rchild) { DestroyBitTree(&((*T)->rchild)); } free(*T); *T = NULL; } } #include "LinkBiTree.h" int main(void) { BitThrTree T,Thrt; BitThrNode *p,*pre,*post; CreateBitTree2(&T,"(A(B(,D(G)),C(E(,H),F)))"); printf("线索二叉树的输出序列:\n"); InOrderThreading(&Thrt,T); printf("序列 前驱标志 结点 后继标志\n"); InOrderTraverse(Thrt,Print); p = FindPoint(Thrt,'D'); pre = InOrderPre(p); printf("元素D的中序直接前驱元素是:%c\n",pre->data); post = InOrderPost(p); printf("元素D的中序直接后驱元素是:%c\n",post->data); p = FindPoint(Thrt,'E'); pre = InOrderPre(p); printf("元素E的中序直接前驱元素是:%c\n",pre->data); post = InOrderPost(p); printf("元素E的中序直接后驱元素是:%c\n",post->data); DestroyBitTree(&Thrt); return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/weichanjuan3/article/details/47110577