本题来自leetcode 102. Binary Tree Level Order Traversal
一、问题描述
给定一个二叉树,返回其节点值的层序遍历。(即从左到右,逐级)【举例】
给定一个二叉树 [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回层序遍历:
[
[3],
[9,20],
[15,7]
]
二、解题思路关键点
1、借助队列,实现层序遍历
2、用两个常量记录当前层元素值cur_layer_count和下一层元素值next_layer_count,每次pop出一个元素,当前层元素值减减;直到当前层元素值减到0,说明该层元素输出完毕,则可将层数layer++
3、二维数组的malloc方法:
int** result = (int**)malloc(layer*sizeof(int*)); //先malloc行
for( i=0; i<layer; i++ )
result[i] = (int*)malloc( (*columnSizes)[i]) * sizeof(int)); //再malloc每一行有多少列
4、注意题目中的参数含义:
** columnSizes:用于存储层序遍历后每一层的结果的长度
* returnSize:用于返回一共多少层
所以最终返回的结果需要一个自定义的二维数组存
三、算法代码
1、队列数据结构定义
/**BFS会用到队列这个数据结构**/ /**循环队列**/ typedef struct { struct TreeNode data[1000]; int front; //头指针 int rear; //尾指针,队列非空则指向队尾最后一个元素后一个位置 }SqQueue; //队列初始化 void InitQueue(SqQueue *Q) { Q->front = 0; Q->rear = 0; } //入队 bool EnQueue(SqQueue *Q, struct TreeNode e) { //判断队列是否满 if( ( Q->rear+1 ) % 1000 == Q->front ) return false; Q->data[Q->rear]=e; Q->rear = (Q->rear+1)%1000; return true; } //出队---删除队首元素,并赋给e struct TreeNode* DeQueue(SqQueue *Q, struct TreeNode* e) { //判断队列是否为空 if( Q->front == Q->rear ) return NULL; *e = Q->data[Q->front]; Q->front = (Q->front+1)%1000; return e; } //队列判空 bool isEmptyQueue(SqQueue *Q) { return Q->front == Q->rear?true:false; }
2、主算法部分
/****************************************** Author:tmw date:2018-5-5 ******************************************/ #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <string.h> struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; }; /** 二叉树的层序遍历借助队列这个数据结构--原理与BFS一样 ** columnSizes:用于存储层序遍历后每一层的结果的长度 * returnSize:用于返回一共多少层 **/ int** levelOrder(struct TreeNode* root, int** columnSizes, int* returnSize) { /**申请并初始化队列**/ SqQueue q; InitQueue(&q); int cur_layer_count = 0; /**记录当前层的结点数**/ int next_layer_count = 0; /**记录下一层结点**/ int layer = 0; /**记录层数**/ /**temp数组用于暂时存储每一层的元素个数**/ int* temp = (int*)malloc(1000*sizeof(int)); temp[0] = 1; /**第一次遍历二叉树:malloc构造对应结果大小的二维数组**/ if( root != NULL ) { struct TreeNode p; /**承接出队元素**/ /**先将当前结点入队**/ EnQueue(&q,*root); cur_layer_count++; /**BFS---构造层序遍历的二维数组**/ while( !isEmptyQueue(&q) ) { /**将当前队列中的元素出队,并将与其有关联的其他结点入队**/ DeQueue(&q,&p); cur_layer_count--; //关联结点入队 if( p.left ) { EnQueue(&q,*(p.left)); next_layer_count++; } if( p.right ) { EnQueue(&q,*(p.right)); next_layer_count++; } if( cur_layer_count == 0 ) //一层已遍历完毕 { layer++; printf("%d\n",layer); temp[layer] = next_layer_count; cur_layer_count = next_layer_count; next_layer_count = 0; } } } /** 传递层数给形参 ** columnSizes:用于存储层序遍历后每一层的结果的长度 * returnSize:用于返回一共多少层 所以最终结果需要一个自定义的二维数组存 **/ *returnSize = layer; *columnSizes = (int*)malloc(layer*sizeof(int)); int i; for( i=0; i<layer; i++ ) (*columnSizes)[i] = temp[i]; free(temp); /**最终结果的二维数组---result**/ int** result; result = (int**)malloc(layer*sizeof(int*)); for( i=0; i<layer; i++ ) result[i] = (int*)malloc((*columnSizes)[i]*sizeof(int)); /**第二次遍历二叉树:将层序结果存入构造好的二维数组result**/ if( root != NULL ) { struct TreeNode p; /**承接出队元素**/ int cur_layer_count = 0; /**记录当前层的结点数**/ int next_layer_count = 0; /**记录下一层结点**/ int layer = 0; /**记录层数**/ int j=0; /**先将当前结点入队**/ EnQueue(&q,*root); cur_layer_count++; /**BFS---传值**/ while( !isEmptyQueue(&q) ) { /**将当前队列中的元素出队,并将与其有关联的其他结点入队**/ DeQueue(&q,&p); cur_layer_count--; result[layer][j] = p.val; j++; /**关联结点入队**/ if( p.left ) { EnQueue(&q,*(p.left)); next_layer_count++; } if( p.right ) { EnQueue(&q,*(p.right)); next_layer_count++; } if( cur_layer_count == 0 ) /**一层已遍历完毕**/ { layer++; /**当前层遍历完毕后进入下一层**/ cur_layer_count = next_layer_count; next_layer_count = 0; j=0; /**下一层的存储从数组0号位置开始**/ } } } /**结果打印**/ int ii,jj; for(ii=0;ii<layer;ii++) { for(jj=0;jj<(*columnSizes)[ii];jj++) printf("%d ",result[ii][jj]); printf("\n"); } return result; }
四、执行结果
leetcode C accept
梦想还是要有的,万一实现了呢~~~ヾ(◍°∇°◍)ノ゙~~~