标签:数据结构
#include<stdio.h> #include<stdlib.h> #define MaxSize 100 /*线索二叉树类型定义*/ typedef char DataType; typedef enum {Link,Thread}PointerTag;//Link=0表示指向孩子节点,Thread=1表示指向前驱节点或后继节点 typedef struct Node{ DataType data; struct Node *lchild,*rchild; //指向左右孩子节点的指针 PointerTag ltag,rtag; //线索标志域 }BiThrNode; typedef BiThrNode* BiThrTree; //二叉树类型 BiThrTree pre;//pre始终指向已经线索化的结点 //利用括号嵌套的字符串建立二叉链表 void CreateBitTree2(BiThrTree *T,char str[]){ char ch; BiThrTree stack[MaxSize]; int top=-1; int flag,k; BiThrNode *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=(BiThrTree)malloc(sizeof(BiThrNode)); 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(BiThrTree 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; //pre指向的结点线索化完毕,使p指向的结点成为前驱 InThreading(p->rchild); //右子树线索化 } } //通过中序遍历二叉树T,使T中序线索化。Thrt是指向头结点的指针 int InOrderThreading(BiThrTree *Thrt,BiThrTree T){ if(!(*Thrt=(BiThrTree)malloc(sizeof(BiThrNode)))) //为头结点分配内存单元 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 Print(BiThrTree 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; } //中序遍历线索二叉树。其中visit是函数指针,指向访问结点的函数实现 int InOrderTraverse(BiThrTree T,int (* visit)(BiThrTree e)){ BiThrTree 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; } //在中序线索树中找结点*p的中序直接前趋 BiThrNode *InOrderPre(BiThrNode *p){ BiThrNode *pre; 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就是最右下端结点 } } //在中序线索树中查找结点*p的中序直接后继 BiThrNode *InOrderPost(BiThrNode *p){ BiThrNode *pre; if(p->rtag==Thread) //如果p的标志域ltag为线索,则p的右子树结点即为后继 return p->rchild; else{ pre=p->rchild; //查找p的右孩子的最左下端结点 while(pre->ltag==Link) pre=pre->lchild; //左子树非空时,沿左链往下查找 return pre; //pre就是最左下端结点 } } //中序遍历线索二叉树,返回元素值为e的结点的指针 BiThrNode *FindPoint(BiThrTree T,DataType e){ BiThrTree 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; } //销毁二叉树操作 void DestroyBitTree(BiThrTree *T){ if(*T){ //如果是非空二叉树 if((*T)->lchild) DestroyBitTree(&((*T)->lchild)); if((*T)->rchild) DestroyBitTree(&((*T)->rchild)); free(*T); *T=NULL; } } void main(){ BiThrTree T,Thrt; BiThrNode *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); system("pause"); }
版权声明:本文为博主原创文章,未经博主允许不得转载|Copyright ©2011-2015,Supernatural, All Rights Reserved.
标签:数据结构
原文地址:http://blog.csdn.net/williamfan21c/article/details/47381675