家譜圖-二叉樹

由於樹有多種表示方式,也能夠不用二叉樹來表示,可是那樣有侷限性, 就好比一個節點有幾個孩子,這個數目都是不肯定的,若是用二叉樹來表示,那樣就比較清楚的顯示出家譜中的人員組成,可是不能用孩子表示法,由於那樣最多隻能表示兩個孩子,可是能夠轉化一下表示方法,用孩子兄弟表示方法來表示,那樣,就能夠有無限多個(理論上)孩子,就是一個節點有兩個指針,一個指向第一個孩子,一個指向它的右兄弟,因此,這種二叉樹能夠表示好多方式,其實和那種二叉樹同樣,只是解釋不同了而已,在計算機中更是差很少,由於計算機沒有這些邏輯,這些都是咱們爲了方便而想象出來的,家譜圖主要實現的功能有增長節點,查詢一個節點的子節點,刪除一個節點(同時刪除)它的子樹。node

 

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 
  4 typedef char TElemType;
  5 
  6 //孩子兄弟表示法
  7 typedef struct Tree{
  8     TElemType data;
  9     struct Tree *firstchild, *rightbro;
 10 }CSNode, *PCSTree;
 11 
 12 PCSTree ptr;
 13 char data;
 14 
 15 void createTree(PCSTree *T)//建立二叉樹
 16 {
 17     TElemType data;
 18     scanf("%c", &data);
 19     getchar();
 20     if(data == ' ')
 21         *T = NULL;
 22     else
 23     {
 24         *T = (PCSTree)malloc(sizeof(CSNode));
 25         (*T) -> data = data;
 26         printf("Please input %c's first child\n", data);
 27         createTree(&(*T) -> firstchild);
 28         printf("Please input %c's right brother\n", data);
 29         createTree(&(*T) -> rightbro);
 30     }
 31 }
 32 
 33 void preOrderTraverse(PCSTree T)//前續遍歷
 34 {
 35     if(T == NULL)
 36         return ;
 37     printf("%c ", T -> data);
 38     preOrderTraverse(T -> firstchild);
 39     preOrderTraverse(T -> rightbro);
 40 }
 41 
 42 void findChild(PCSTree T, char data)//查找某個節點的孩子
 43 {
 44     if (T == NULL)
 45         return ;
 46     PCSTree p;
 47     p = T->firstchild;
 48     if (T->data == data)
 49     {
 50         if(p == NULL)
 51         {
 52             printf("No member!\n");
 53             return;
 54         }
 55         while (p->rightbro != NULL)//打印出來他全部的孩子
 56         {
 57             printf("%c ", p->data);
 58             p = p->rightbro;
 59         }
 60         printf("%c\n", p->data);
 61         return ;
 62     }
 63     else
 64     {
 65         findChild(T->firstchild, data);//若是找不到的話,繼續找他的子節點
 66         findChild(T->rightbro, data);
 67     }
 68 }
 69 
 70 int addMember(PCSTree *T)//添加新成員
 71 {
 72     if(*T == NULL)//用於遞歸時判斷退出條件
 73         return 0;
 74     PCSTree pt;
 75     if ((*T)->data == data)//找到父節點
 76     {
 77         if ((*T)->firstchild != NULL)
 78         {
 79             pt = (*T)->firstchild;
 80             while(pt->rightbro != NULL)//找到最右邊的一個添加新節點
 81                 pt = pt->rightbro;
 82             pt->rightbro = ptr;
 83             return 1;//添加成功, 返回1
 84         }
 85         (*T)->firstchild = ptr;
 86         return 1;
 87     }
 88 
 89     if (addMember(&(*T)->firstchild) == 1)//遞歸再找匹配的父節點
 90         return 1;
 91     if (addMember(&(*T)->rightbro) == 1)
 92         return 1;
 93     return 0;
 94 }
 95 
 96 void findAndFree(PCSTree *T)//找到傳過來的某個節點而且將它釋放掉,而且釋放掉它全部的子節點
 97 {
 98     if(*T == NULL)
 99         return;
100     PCSTree p1, p2;
101     p1 = (*T)->firstchild;
102     p2 = (*T)->rightbro;
103     findAndFree(&p1);
104     findAndFree(&p2);
105     free(*T);
106 }
107 
108 int deleteMember(PCSTree *T)//刪除節點函數(刪除其子樹)
109 {
110     PCSTree pt;
111     if(*T == NULL)
112         return 0;
113     //相似鏈表中的刪除,要刪除當前元素,先要找到它的前一個
114     if((*T)->firstchild == NULL && (*T)->rightbro == NULL)
115     {
116         if ((*T)->data == data)
117         {
118             free(*T);
119             return 1;
120         }
121         return 0;
122     }
123     //若是是它的子節點
124     if((*T)->firstchild != NULL && (*T)->firstchild->data == data)
125     {
126         pt = (*T)->firstchild;
127         if (pt->rightbro != NULL)
128         {
129             (*T)->firstchild = pt->rightbro;
130         }
131         else
132             (*T)->firstchild = NULL;
133         if(pt->firstchild != NULL)
134             findAndFree(&(pt->firstchild));
135         free(pt);
136         return 1;
137     }
138     //若是是它的右兄弟節點
139     else if ((*T)->rightbro != NULL && (*T)->rightbro->data == data)
140     {
141         pt = (*T)->rightbro;
142         if (pt->rightbro != NULL)
143         {
144              (*T)->rightbro = pt->rightbro;
145 
146         }
147         else
148             (*T)->rightbro = NULL;
149         if(pt->firstchild != NULL)
150             findAndFree(&(pt->firstchild));
151         free(pt);
152         return 1;
153     }
154     //若是都不是,繼續遞歸 找
155     if(deleteMember(&(*T)->firstchild))
156         return 1;
157     if(deleteMember(&(*T)->rightbro))
158         return 1;
159     return 0;
160 }
161 
162 
163 int main()
164 {
165 //    freopen("in.txt", "r", stdin);
166     PCSTree T;
167     printf("Input root Node:\n");
168     createTree(&T);//create binary tree
169     printf("The previous traverse are:\n");
170     preOrderTraverse(T);//previous traverse the tree
171     printf("\n");
172     char newdata;
173     int choice;
174     do{
175         printf("1. find some node's kids   2. add member\n");
176         printf("3. delete some node        4. previous traverse the tree\n");
177         printf("0. exit\n");
178         scanf("%d", &choice);
179         switch(choice)
180         {
181             case 1:
182                 printf("\nPlease input you want find child name:\n");
183                 getchar();
184                 scanf("%c", &data);
185                 findChild(T, data);
186                 printf("\n");
187                 break;
188             case 2:
189                 if(T == NULL)
190                 {
191                     printf("Input root node:\n");
192                     getchar();
193                     createTree(&T);
194                 }
195                 else
196                 {
197                     printf("Please input you want add data\n");
198                     printf("Format: father child\n");
199                     ptr = (PCSTree)malloc(sizeof(CSNode));
200                     ptr->firstchild = ptr->rightbro = NULL;
201                     getchar();
202                     scanf("%c %c", &data, &newdata);
203                     ptr->data = newdata;
204                     addMember(&T);
205                     preOrderTraverse(T);
206                     printf("\n");
207                 }
208                 break;
209             case 3:
210                 if(T == NULL)
211                 {
212                     printf("No member\n");
213                     break;
214                 }
215                 printf("Please input you want delete node\n");
216                 getchar();
217                     scanf("%c", &data);
218                 if(data == T->data)
219                 {
220                     findAndFree(&T);
221                     T = NULL;
222                 }
223                 else
224                     deleteMember(&T);
225                 break;
226             case 4:
227                 if(T != NULL)
228                     preOrderTraverse(T);
229                 else
230                     printf("No member");
231                 printf("\n");
232                 break;
233             default:
234                 break;
235         }
236     }while(choice != 0);
237     return 0;
238 }
相關文章
相關標籤/搜索