03-树2 List Leaves
此题需要按要求输出叶节点,在输入序列中找到根节点构造好二叉树以及利用队列保存并按序输出叶节点是两大关键。
1 #include <stdio.h> 2 #include <stdlib.h> 3 #define MaxSize 10 4 5 typedef struct TreeNode *BinTree; 6 struct TreeNode{ 7 char Data; 8 char LeftD; 9 char RightD; 10 BinTree Left; 11 BinTree Right; 12 }; 13 14 struct Node{ 15 BinTree BT; 16 struct Node *Next; 17 }; 18 19 struct QNode{ 20 struct Node *rear; 21 struct Node *front; 22 }; 23 24 typedef struct QNode *Queue; 25 26 BinTree BuildTree() 27 { 28 BinTree T[MaxSize], t; 29 t = T[0]; 30 T[0] = (BinTree)malloc(sizeof(struct TreeNode)); 31 int i, j, N, Root, a, b; 32 char ln, rn; 33 34 int checkRoot[MaxSize] = {2}; 35 scanf("%d\n", &N); 36 for(i = 0; i < N; i++) 37 checkRoot[i] = 1; 38 for(i = 0; i < N; i++){ 39 T[i] = (BinTree)malloc(sizeof(struct TreeNode)); 40 T[i]->Data = i + '0'; 41 scanf("%c %c\n", &T[i]->LeftD, &T[i]->RightD); 42 if(T[i]->LeftD == '-') 43 T[i]->Left = NULL; 44 else{ 45 a = T[i]->LeftD - '0'; 46 checkRoot[a] = 0; 47 } 48 if(T[i]->RightD == '-') 49 T[i]->Right = NULL; 50 else{ 51 b = T[i]->RightD - '0'; 52 checkRoot[b] = 0; 53 } 54 } 55 for(i = 0; i < N; i++){ 56 ln = T[i]->LeftD; 57 rn = T[i]->RightD; 58 for(j = 0; j < N; j++){ 59 if(ln != '-' && ln == T[j]->Data) 60 T[i]->Left = T[j]; 61 if(rn != '-' && rn == T[j]->Data) 62 T[i]->Right = T[j]; 63 } 64 } 65 for(i = 0; i < N; i++){ 66 if(checkRoot[i] == 1) 67 Root = i; 68 } 69 t = T[Root]; 70 return t; 71 } 72 73 Queue CreateQueue(int M) 74 { 75 Queue PtrQ; 76 PtrQ = (Queue)malloc(sizeof(struct QNode)); 77 PtrQ->front = (struct Node*)malloc(sizeof(struct Node)); 78 PtrQ->rear = PtrQ->front = NULL; 79 return PtrQ; 80 } 81 82 int isEmpty(Queue PtrQ) 83 { 84 return (PtrQ->front == NULL); 85 } 86 87 void AddQ(BinTree T, Queue PtrQ) 88 { 89 struct Node *tmpCell; 90 tmpCell = (struct Node*)malloc(sizeof(struct Node)); 91 tmpCell->BT = T; 92 tmpCell->Next = NULL; 93 if(PtrQ->front == NULL){ 94 PtrQ->front = tmpCell; 95 PtrQ->rear = tmpCell; 96 }else{ 97 PtrQ->rear->Next = tmpCell; 98 PtrQ->rear = tmpCell; 99 } 100 } 101 102 BinTree DeleteQ(Queue PtrQ) 103 { 104 struct Node *FrontCell; 105 BinTree FrontElem; 106 if(PtrQ->front == NULL) 107 return NULL; 108 FrontCell = PtrQ->front; 109 if(PtrQ->front == PtrQ->rear) 110 PtrQ->front = PtrQ->rear = NULL; 111 else 112 PtrQ->front = PtrQ->front->Next; 113 FrontElem = FrontCell->BT; 114 free(FrontCell); 115 return FrontElem; 116 } 117 118 void PrintLeaves(BinTree BT) 119 { 120 Queue Q; 121 BinTree t; 122 int LeaveDatas[MaxSize], i = 0, j; 123 if(!BT) 124 return; 125 Q = CreateQueue(MaxSize); 126 AddQ(BT, Q); 127 while(!isEmpty(Q)){ 128 t = DeleteQ(Q); 129 if(t->Left == NULL && t->Right == NULL){ 130 LeaveDatas[i] = t->Data - '0'; 131 i++; 132 } 133 if(t->Left) 134 AddQ(t->Left, Q); 135 if(t->Right) 136 AddQ(t->Right, Q); 137 } 138 printf("%d", LeaveDatas[0]); 139 for(j = 1; j < i; j++) 140 printf(" %d", LeaveDatas[j]); 141 } 142 143 int main(int argc, char const *argv[]) 144 { 145 BinTree BT; 146 BT = BuildTree(); 147 PrintLeaves(BT); 148 return 0; 149 }
其中,找根节点是用节点标记的方式,一开始将每个节点标记位都记为1,在构造过程中,若这个节点成为了别的节点的子节点,则标记位置0。最后看哪个节点没有成为任何其它节点的子节点,是为根节点。判断时需注意字符型和整型的转换。
构造好树之后按要求遍历,过程中注意将叶节点放入队列,最后按序输出即可。