本题来自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
梦想还是要有的,万一实现了呢~~~ヾ(◍°∇°◍)ノ゙~~~