C语言二叉树层序遍历--malloc二维数组存储每层结果

本题来自leetcode 102Binary 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

                                                                                                              梦想还是要有的,万一实现了呢~~~ヾ(◍°∇°◍)ノ゙~~~



猜你喜欢

转载自blog.csdn.net/qiki_tangmingwei/article/details/80210148