(leetcode)二叉树的层次遍历-c语言实现
这段代码,在后面跑测试用例时,出现了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; }