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