#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(); }
線索化樹
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.