/**************************************************************** * * 文件名:Rstree.c * * 文件描述:樹相關操作的遞歸算法實現 * * 創建人:顏清國 2006年4月15日 * * * 修改記錄: * **************************************************************/ #include "stdio.h" #include"stdlib.h" #include"conio.h" #define LEFT 1 #define RIGHT 2 #define MAX 20 /************************************** 定義樹的結構體 ***************************************/ typedef struct tagtree { char data; /*數據域*/ int flag; /*非遞歸操作時用來做標誌*/ struct tagtree*lchild; /*指向左孩子的指針域*/ struct tagtree*rchild; /*指向右孩子的指針域*/ }tree; /**************************************** 創建一棵樹,要求這棵樹用括號表示法輸入 *****************************************/ 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 OutTree(tree *root) { if(root != NULL) { printf("%c",root->data); /*先輸出根結點*/ if(root->lchild != NULL || root->rchild != NULL) { printf("("); OutTree(root->lchild); /*處理左子樹*/ if(root->rchild != NULL) { printf(","); } OutTree(root->rchild); /*處理右子樹*/ printf(")"); } } } /************************************************ 遞歸先序遍歷二叉樹 ************************************************/ void RsPrePath(tree *root) { if(root!=NULL) { printf("%c ",root->data); /*遇到根結點先輸出*/ RsPrePath(root->lchild); /*遇到根結點左子數先輸出, 直到空,返回是輸出左子數 根結點右子數*/ RsPrePath(root->rchild); /*同樣處理右子數*/ } } /************************************************ 遞歸中序遍歷二叉樹 ************************************************/ void RsMidPath(tree *root) { if(root!=NULL) { RsMidPath(root->lchild); printf("%c ",root->data); RsMidPath(root->rchild); } } /************************************************ 遞歸後序遍歷二叉樹 ************************************************/ void RsLastPath(tree *root) { if(root!=NULL) { RsLastPath(root->lchild); RsLastPath(root->rchild); printf("%c ",root->data); } } /*********************************************** 遞歸遍歷二叉樹演示 ************************************************/ void RsTreeDemo(tree*root) { printf("/nthe PrePath is:"); RsPrePath(root); printf("/nthe MidPath is:"); RsMidPath(root); printf("/nthe LastPath is:"); RsLastPath(root); } /************************************************ 用樹形表示法輸出樹 *************************************************/ 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); /*遞歸處理右子樹*/ } } } /***************************************************** 根據DATA域,查找第一個遇到的結點,並返回該結點 *****************************************************/ tree* IndexNode(tree *root,char data,int *high,int temp) { if(root == NULL) { (*high)=0; return NULL; } else if(root->data == data) /*找到所要找的結點*/ { (*high) = temp; return root; } else { if(IndexNode(root->lchild,data,high,temp+1)==NULL) { IndexNode(root->rchild,data,high,temp+1);/*如果在左 子樹中沒有找到*/ } } } /**************************************************** 找某一結點的左子樹 ****************************************************/ tree* FindLchild(tree * node) { if(node !=NULL) { return node->lchild; } else return NULL; } /**************************************************** 找某一結點的右子樹 ****************************************************/ tree* FindRchild(tree * node) { if(node !=NULL) { return node->rchild; } else return NULL; } /**************************************************** 先序遍歷查找所有葉子結點 ****************************************************/ void FindLeaft(tree *root) { if(root == NULL) return; if(root->lchild == NULL && root->rchild == NULL) { printf("%c ",root->data); } FindLeaft(root->lchild); FindLeaft(root->rchild); } void main() { tree *root; int high; char str[100]; clrscr(); printf("Please input the Tree string:"); gets(str); CreateTree(&root,str); printf("/nthe Tree is:"); DispTree(root,10,4,5); gotoxy(2,15); FindLeaft(root); /*printf("/n%c",IndexNode(root,'t',&high,1)->data); printf("/n%d",high);*/ /*RsTreeDemo(root);*/ getch(); }
樹相關操作的遞歸算法實現
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.