描述
给定一个二叉树,返回其按层次遍历的节点值。 (即逐层地,从左到右访问所有节点)。
例如:
给定二叉树: [3,9,20,null,null,15,7],
返回其层次遍历结果:
1 2 3 4 5 [ [3 ], [9 ,20 ], [15 ,7 ] ]
来源:力扣(LeetCode)
链接:102. Binary Tree Level Order Traversal
解题思路
通常,二叉树的层序遍历可以借助队列进行实现,具体的算法实现可以设置一个队列结构,遍历从根节点开始,首先将根节点指针入队,然后开始执行下面三个操作:
从队列中取出一个元素
访问该元素所指节点的值
若该元素所指节点的左、右孩子节点非空,则将其左、右孩子的指针顺序入队
不断执行以上三个步骤,直到队列为空,再无元素可取,二叉树的层序遍历就完成了。
回到本题,首先当然是定义队列结构即相关操作函数,主要有Qinit, push, pop, isFull, isEmpty等等。
具体代码见解法一,代码当中会给出相关注释。
显然,如果用C语言需要自己实现队列,从头开始造轮子,代码比较多,如果使用递归,代码会简洁很多。
递归的主要思路是:传递变量level来表示处在第几层,使用rcs数组存放每层中已经存放了几个元素。采用 左子树 ->本节点 ->右子树 的遍历顺序,达到从左到右的添加顺序。 或者 本节点 -> 左子树 ->右子树 顺序,左边在右边前面即可。
具体代码见解法二。
代码
解法一:迭代
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 #define QMAX 1024 typedef struct TreeNode * Tree ;typedef struct Queue { Tree Node[QMAX]; int front; int rear; }Queue; void Qinit (Queue *q) { q->front = q->rear = 0 ; } bool isFull (Queue *q) { return ((q->rear + 1 ) % QMAX == q->front); } bool isEmpty (Queue *q) { return q->rear == q->front; } bool push (Queue *q, Tree node) { if (isFull(q)) return false ; q->Node[q->rear] = node; q->rear = (q->rear + 1 ) % QMAX; return true ; } Tree pop (Queue *q) { if (isEmpty(q)) { return NULL ; } Tree node; node = q->Node[q->front]; q->front = (q->front + 1 ) % QMAX; return node; } int ** levelOrder (Tree root, int * returnSize, int ** returnColumnSizes) { *returnSize = 0 ; if (!root){ return NULL ; } Queue queue ; Qinit(&queue ); int *level = (int *)calloc (1 , sizeof (int ) * QMAX); push(&queue , root); int height = 0 ; level[height] = 1 ; int **result = (int **)malloc (sizeof (int *) * QMAX); while (!isEmpty(&queue )) { height++; result[height - 1 ] = (int *)malloc (sizeof (int *) * level[height - 1 ]); for (int i = 0 ; i< level[height - 1 ]; i++) { root = pop(&queue ); result[height - 1 ][i] = root->val; if (root->left) { push(&queue , root->left); level[height]++; } if (root->right) { push(&queue , root->right); level[height]++; } } } *returnColumnSizes = level; *returnSize = height; return result; }
解法二:递归
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 typedef struct TreeNode * Tree ;#define LEV 1024 #define LEN 1024 void get (Tree node, int level, int **ret, int *ret_index, int *rcs) { if (!node) return NULL ; if (!ret[level]) { ret[level] = (int *)malloc (sizeof (int ) * LEN); rcs[level] = 0 ; } if (level > *ret_index) { *ret_index = level; } ret[level][rcs[level]++] = node->val; get(node->left, level + 1 , ret, ret_index, rcs); get(node->right, level + 1 , ret, ret_index, rcs); } int ** levelOrder (Tree root, int * returnSize, int ** returnColumnSizes) { int **ret = (int **)malloc (sizeof (int *) * LEV); int *rcs = (int *)malloc (sizeof (int ) * LEV); int ret_index = 0 ; memset (ret, 0 , sizeof (int *) * LEV); memset (rcs, 0 , sizeof (int ) * LEV); get(root, 0 , ret, &ret_index, rcs); *returnSize = root==NULL ? 0 : ret_index + 1 ; *returnColumnSizes = rcs; return ret; }
参考