#include "stdio.h" #include "stdlib.h" #define LEFT 1 #define RIGHT 2 #define MAX 20 /************************************** 定义树的结构体 ***************************************/ typedef struct tagtree { char data; /*数据域*/ int ltag; /*线索化时用来标志是左孩子还是前驱*/ int rtag; /*线索化时用来标志是右孩子还是后继*/ struct tagtree*lchild; /*指向左孩子的指针域*/ struct tagtree*rchild; /*指向右孩子的指针域*/ }tree; tree *pre=NULL; /*全局指针,线索化时用来保存前一个结点*/ /**************************************** 创建一棵树,要求这棵树用括号表示法输入 *****************************************/ void CreateTree(tree **root,char *str) { char ch; tree *stack[MAX],*lp=NULL,*temp; /*定义一个指向树的一个栈, 用来创建其结点的父子关系*/ int top=-1,flag; /*指向树栈的栈顶,flag用来标记左右孩子*/ (*root)=NULL; /*特别注意这里一定要先将指向根结点的指针附空,否则 在XP系统下就会出大错*/ while((*str)!='/0') { ch=(*str); switch(ch) { case '(': /*下去的DATA值将作为栈顶结点的左右孩子*/ top++; stack[top] = lp; /*将双亲结点入栈*/ flag = LEFT; /*标记其下一个结点将作为此栈顶结点的 左孩子*/ break; case ',': flag = RIGHT; /*标记为下去结点将作为此栈顶结点的 右孩子*/ break; case ')': top--; /*将栈顶结点退栈,这样才能保证双亲及 其对应孩子的正确配对*/ break; default: /*此时CH为DATA域*/ lp = (tree*)malloc(sizeof(tree)); /*创建一个结点*/ lp->data = ch; lp->lchild = NULL; lp->rchild = NULL; if((*root) == NULL) /*是树的根结点*/ (*root) = lp; else { /*注意此处不能用这种表达方式*/ /* temp = (flag == LEFT) ? stack[top]->lchild : stack[top]->rchild; temp = lp; */ switch(flag) { case RIGHT: /*插到右结点*/ stack[top]->rchild = lp; break; case LEFT: /*插到左结点*/ stack[top]->lchild = lp; break; } } break; } str++; } } /************************************************ 用树形表示法输出树 *************************************************/ void DispTree(tree *root,int x,int y,int n) /*n用来控制第一层树的高度*/ { int i=0; if(root !=NULL) { gotoxy(x,y); /*到相应结点输出*/ printf("%c",root->data); if(root->lchild != NULL) /*处理左子树,这里只有第一次N为可变的,*/ { i=1; /*为的是能够输出整棵树,而不会被覆盖,*/ while(ilchild,x-n,y+n,2); /*递归处理左子树*/ } if(root->rchild != NULL) { i=1; while(irchild,x+n,y+n,2); /*递归处理右子树*/ } } } /****************************************************** 对一棵树进行中序线索化 ********************************************************/ void inthread(tree*root) { if(root!=NULL) { inthread(root->lchild); /*先线索化左孩子*/ if(root->lchild ==NULL) /*线索化根结点*/ { root->lchild=pre; root->ltag=1; /*ltag=1表示指向的是前驱*/ } else root->ltag=0; if(pre!=NULL) /*注意这里要加个判断,否则在第一个时pre==NULL*/ { /*编译出错,NULL POINTER ASSGINED*/ if(pre->rchild == NULL) { pre->rchild=root; pre->rtag=1; /*rtag=1表示指向的是后继*/ } else pre->rtag=0; } pre=root; inthread(root->rchild); /*最后线索化左孩子*/ } } /*************************************************** 访问中序线索树中的每一个结点 ****************************************************/ void VsInthread(tree*root) { tree*lp; if(root!=NULL) { while(root->ltag==0) /*有左孩子,继续查找左孩子*/ root=root->lchild; printf("%c ",root->data); while(root->rchild !=NULL) { if(root->rtag==1) root=root->rchild; /*直接访问后续结点*/ else { root=root->rchild; /*ROOT有右孩子,要找到右孩子的左孩子*/ while(root->ltag == 0) root=root->lchild; } printf("%c ",root->data); } } } void main() { char str[20]; tree*root=NULL; printf("Input the str:"); gets(str); CreateTree(&root,str); printf("the result is:"); DispTree(root,10,4,5); getch(); inthread(root); printf("/n/nthe thread visit result is:"); VsInthread(root); getch(); }
线索化树
最新推荐文章于 2024-02-17 18:05:59 发布