C語言 03-樹2 List Leaves
Given a tree, you are supposed to list all the leaves in the order of top down, and left to right.
Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (≤10) which is the total number of nodes in the tree – and hence the nodes are numbered from 0 to N−1. Then N lines follow, each corresponds to a node, and gives the indices of the left and right children of the node. If the child does not exist, a “-” will be put at the position. Any pair of children are separated by a space.
Output Specification:
For each test case, print in one line all the leaves’ indices in the order of top down, and left to right. There must be exactly one space between any adjacent numbers, and no extra space at the end of the line.
Sample Input:
8
1 -
- -
0 -
2 7
- -
- -
5 -
4 6
Sample Output:
4 1 5
Show me the Code:
#include <stdio.h>
#include <stdlib.h>
#ifndef NULL
#define NULL 0
#endif // NULL
#define MAXSIZE 10
#define Null -1
typedef int ElementType;
struct QNode
{
ElementType Data;
struct QNode *Next;
};
typedef struct QNode *Position;
typedef Position Queque;
struct TNode
{
ElementType Data;
int left;
int right;
} T[MAXSIZE];
Queque CreateQueue();
int add(Queque q, ElementType e);
ElementType Delete(Queque q);
int IsEmpty(Queque q);
int BuildTree();
void LevelOrderTraversal(int root);
int main()
{
int root;
root = BuildTree();
LevelOrderTraversal(root);
return 0;
}
/*佇列抽象資料結構*/
Queque CreateQueue()
{
Queque q;
q = (Queque)malloc(sizeof(struct QNode));
q->Data = 0;
q->Next = NULL;
return q;
}
int add(Queque q, ElementType e)
{
Position p,tmp;
if(!q)
q = CreateQueue();
tmp = q;
while(tmp->Next)
tmp = tmp->Next;
p = (Position)malloc(sizeof(struct QNode));
p->Data = e;
p->Next = NULL;
tmp->Next = p;
return 0;
}
ElementType Delete(Queque q)
{
ElementType First;
Position tmp;
if(!q || q->Next == NULL)
return NULL;
else
{
tmp = q->Next;
q->Next = tmp->Next;
First = tmp->Data;
free(tmp);
return First;
}
}
int IsEmpty(Queque q)
{
return(q->Next == NULL);
}
/*二叉樹靜態連結串列資料結構*/
int BuildTree()
{
int N;
scanf("%d",&N);
getchar();
if(N)
{
int i,root;
int check[N];
char cl,cr;
for(i=0;i<N;i++)
check[i] = 0;
for(i=0;i<N;i++)
{
scanf("%c %c",&cl,&cr);
getchar();
if(cl!='-')
{
T[i].left = cl-'0';
check[T[i].left] = 1;
}
else
T[i].left = Null;
if(cr!='-')
{
T[i].right = cr-'0';
check[T[i].right] = 1;
}
else
T[i].right = Null;
}
for(i=0;i<N;i++)
{
if(check[i]==0){
root = i;
break;
}
}
return root;
}
else
return Null;
}
void LevelOrderTraversal(int root)
{
Queque q;
q = CreateQueue();
if(root<0)
return;
int tmp,flag = 1;
add(q,root);
while(!IsEmpty(q))
{
tmp = Delete(q);
if(T[tmp].left == Null && T[tmp].right == Null)
{
if(flag)
{
printf("%d",tmp);
flag = 0;
}
else
printf(" %d",tmp);
}
else if(T[tmp].left == Null)
add(q,T[tmp].right);
else if(T[tmp].right == Null)
add(q,T[tmp].left);
else
{
add(q,T[tmp].left);
add(q,T[tmp].right);
}
}
}
結果
思路與問題
問題不難,包括兩個部分,建樹和層次遍歷找葉節點。
在樹的同構中我們學習了通過靜態連結串列建樹的方法,此處我們同樣通過建立一個結構體陣列,將輸入內容先存下來,通過結構所包含的left和right變數指向兒子節點的陣列下標。
層次遍歷部分,不能通過遞迴實現,在mooc中,何欽銘老師已經講述了通過佇列實現層次遍歷的方法,此處即是用這樣的思路對樹進行遍歷,遇到沒有兒子節點的結點,就將他print出來