這段代碼,在后面跑測試用例時,出現了stack-overflow,但是原因還不清楚。
問題如下:
二叉樹的層次遍歷
給定一個二叉樹,返回其按層次遍歷的節點值。 (即逐層地,從左到右訪問所有節點)。
例如:
給定二叉樹: [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回其層次遍歷結果:
[ [3], [9,20], [15,7] ]
因為要輸出一個二維數組,那么我需要定義一個兩重鏈表,具體定義如下:
/* 鏈表節點 用於存儲輸出結果 */ struct listNode { int val; struct listNode *next; }; struct list { int count; struct listNode *head; struct listNode *tail; struct list *next; }; struct list_list { int count; struct list *head; struct list *tail; };
鏈表的一些操作如下:
void init_list(struct list *l) { l->count = 0; l->head = NULL; l->tail = NULL; l->next = NULL; } void init_list_list(struct list_list *l) { l->count = 0; l->head = NULL; l->tail = NULL; } void add_new_node(struct list *l, struct listNode *node) { if (!l->head) { l->head = node; l->tail = node; l->count = 1; return; } l->tail->next = node; l->tail = node; l->count++; } void add_new_list(struct list_list *ll, struct list *l) { if (ll->head == NULL) { ll->head = l; ll->tail = l; ll->count = 1; return; } ll->tail->next = l; ll->tail = l; ll->count++; }
鏈表創建如下:
struct list_list * create_list_list() { struct list_list *ll = malloc(sizeof(struct list_list)); if (ll) { init_list_list(ll); } return ll; } struct list * create_list() { struct list *l = malloc(sizeof(struct list)); if (l) { init_list(l); } return l; }
另外需要定義一個隊列,用於存放每個樹節點
/* 隊列節點,用於存儲已經遍歷過的根節點 */ struct queue_node { void *entry; struct queue_node *next; }; struct queue { struct queue_node *front; struct queue_node *rear; };
隊列的一些簡單操作實現如下:
/* 隊列節點,用於存儲已經遍歷過的根節點 */ struct queue_node { void *entry; struct queue_node *next; }; struct queue { struct queue_node *front; struct queue_node *rear; }; void init_queue(struct queue *q) { q->front = NULL; q->rear = NULL; } void queue_push(struct queue *q, void *np) { struct queue_node *node = malloc(sizeof(struct queue_node)); node->entry = np; node->next = NULL; if (q->rear == NULL) { q->rear = node; q->front = node; } else { q->rear->next = node; q->rear = node; } } void *queue_pop(struct queue *q) { struct queue_node *np = q->front; void *entry = NULL; if (np) { entry = np->entry; if (np->next == NULL) q->rear = NULL; q->front = np->next; free(np); } return entry; }
struct queue * create_queue() { struct queue *q = malloc(sizeof(struct queue)); if (q) { init_queue(q); } return q; }
主函數的具體實現思想為,遍歷根節點,將其存入隊列中,然后在隊列中插入一個flag標記,之后進入一個while循環,循環中,每次從隊列中取出一個成員,將該成員存入到用於輸出的二層鏈表中,然后判斷其左右孩子是否為空,不為空,則其左右孩子入隊列。然后再循環,當從隊列中取出的是flag標志后,並且隊列中還沒空,那么就在這個隊列中再插入一個flag標志,表示這一層的遍歷結束,可以輸出這一層的鏈表。如此循環,直到所有節點都入隊列,讀到最后一個flag標記,並且隊列為空,那么整個遍歷流程結束。后面就是把二層鏈表輸出成一個二維數組。
代碼如下:
int** levelOrder(struct TreeNode* root, int* returnSize, int** returnColumnSizes){ struct list_list *ll; struct list *subList; struct listNode *head; struct queue *q; struct TreeNode *pNode = NULL; struct listNode *newnode = NULL; int **r; int *subr; struct list *l; int i,j; int *size; int *resize; if (!root || !returnSize || !returnColumnSizes) return; q = create_queue(); ll = create_list_list(); l = create_list(); add_new_list(ll, l); queue_push(q, (void*)root); queue_push(q, FINISH_FALG); while (q->front != NULL) { pNode = (struct TreeNode *)queue_pop(q); if (pNode == FINISH_FALG) { if (q->front == NULL) break; /* 創建新的鏈表,在總鏈表中插入新的鏈表 */ l = create_list(); add_new_list(ll, l); /* 在當前隊列中再插入一個終結標志 */ queue_push(q, FINISH_FALG); continue; } /* 該節點插入到當前鏈表中 */ newnode = create_node(pNode->val); add_new_node(l, newnode); /* 將當前節點的左右孩子加入隊列中 */ if (pNode->left != NULL) { queue_push(q, (void*)pNode->left); } if (pNode->right != NULL) { queue_push(q, (void*)pNode->right); } } r = (int **)malloc(sizeof(int *) * ll->count); resize = (int *)malloc(sizeof(int *) * ll->count); subList = ll->head; while(subList && i < ll->count) { subr = (int *)malloc(sizeof(int) * subList->count); head = subList->head; j = 0; while(head && j < subList->count) { subr[j] = head->val; j++; head = head->next; } resize[i] = subList->count; r[i] = subr; i++; subList = subList->next; } *returnSize = ll->count; *returnColumnSizes = resize; return r; }
