TOP101题解 | BM41#输出二叉树的右视图#

输出二叉树的右视图

https://www.nowcoder.com/practice/c9480213597e45f4807880c763ddd5f0

#include <stdlib.h>
struct QueueNode 
{
    struct TreeNode* Tree_Node;
    struct QueueNode* next;
};

struct Queue 
{
    struct QueueNode* front;
    struct QueueNode* rear;
    int length;
};

// 创建一个空队列
struct Queue* Queue_create() 
{
    struct Queue* queue = (struct Queue*)malloc(sizeof(struct Queue));
    queue->front = queue->rear = NULL;
    queue->length = 0;
    return queue;
}

// 入队
void Queue_in(struct Queue* queue, struct TreeNode* Tree_Node) 
{
    struct QueueNode* newNode = (struct QueueNode*)malloc(sizeof(struct QueueNode));
    newNode->Tree_Node = Tree_Node;
    newNode->next = NULL;

    if (queue->length == 0) 
    {
        queue->front = queue->rear = newNode;
    } else 
    {
        queue->rear->next = newNode;
        queue->rear = newNode;
    }
    queue->length++;
}

// 出队
struct TreeNode* Queue_out(struct Queue* queue) {
    if (queue->length == 0) 
    {
        return NULL;
    }

    struct TreeNode* Tree_Node = queue->front->Tree_Node;
    struct QueueNode* temp = queue->front;

    queue->front = queue->front->next;

    if (queue->front == NULL) 
    {
        queue->rear = NULL;
    }

    free(temp);
    queue->length--;
    return Tree_Node;
}

 /** *******************************************************************************************
 * @brief   根据前序和中序构建二叉树
 * @param preOrder int整型一维数组 先序遍历
 * @param preStart int preOrder数组 子树起始下标
 * @param preEnd int preOrder数组 子树结束下标
 * @param inOrder int整型一维数组 中序遍历
 * @param vinStart int inOrder数组 子树起始下标
 * @param vinEnd int inOrder数组 子树结束下标
 * @return struct TreeNode* 二叉树根节点
 *********************************************************************************************/
 struct TreeNode* buildTree(int* preOrder, int preStart, int preEnd, int* inOrder, int vinStart, int vinEnd) {
    if(preStart > preEnd || vinStart > vinEnd)
    {
        return NULL;
    }
    
    // 根节点的值为前序遍历的第一个元素
    int rootVal = preOrder[preStart];
    struct TreeNode* root = (struct TreeNode*)malloc(sizeof(struct TreeNode));
    root->val = rootVal;
    root->left = root->right = NULL;
    
    // 在中序遍历数组中找到根节点的位置
    int rootIdx = vinStart;
    while(rootIdx <= vinEnd)
    {
        if(rootVal == inOrder[rootIdx])
        {
            break;
        }
        rootIdx++;
    }
    
    // 左右子树的节点数
    int leftLen = rootIdx - vinStart;
    int rightLen = vinEnd - rootIdx;
    
    /* 递归构建左子树和右子树:
        左子树的前序和中序
        右子树的前序和中序
    */
    root->left = buildTree(preOrder, preStart + 1, preStart + leftLen,  inOrder, vinStart,  rootIdx - 1);
    root->right = buildTree(preOrder, preStart + leftLen + 1, preEnd, inOrder,  rootIdx + 1, vinEnd);
    
    return root;
}

/************************************************************************************************
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 求二叉树的右视图
* @author Senky
 * @date 2023.08.20
 * @par url https://www.nowcoder.com/creation/manager/content/584337070?type=column&status=-1
 * @brief   
 *          ①首先通过给定前序遍历和中序遍历的结果来重建二叉树
 *          ②使用层序遍历将最后一个结点存储在结果数组
 * @param preOrder int整型一维数组 先序遍历
 * @param preOrderLen int preOrder数组长度
 * @param inOrder int整型一维数组 中序遍历
 * @param inOrderLen int inOrder数组长度
 * @return int整型一维数组
 * @return int* returnSize 返回数组行数
 * *********************************************************************************************/
int* solve(int* preOrder, int preOrderLen, int* inOrder, int inOrderLen, int* returnSize ) {
    // write code here
    int* result = (int*)calloc(1,sizeof(int));//一个int类型空间,初始化为0
    *returnSize = 0;//行数默认为0

    /*每一个值都必须是合法值-即不是空树*/
    if(NULL == preOrder || NULL == inOrder || preOrderLen != inOrderLen || preOrderLen < 0)
    {
        return NULL;
    }

    //构建二叉树
    struct TreeNode* root = buildTree(preOrder, 0, preOrderLen - 1, inOrder, 0, inOrderLen - 1);

    //创建空队列
    struct Queue* queue = Queue_create();

    //根节点入队
    Queue_in(queue, root);

    //当前层序遍历层数的结点个数
    int levelNodes = 1;

    //当前层数(从0开始)
    int currentlevel = 1;

    //层序遍历
    while (queue->length != 0) 
    {
        //当前层结点个数
        levelNodes = queue->length;

        for (int i = 0; i < levelNodes; i++) 
        {
            struct TreeNode* node = Queue_out(queue);

            //当前层的最后一个元素存入数组,数组长度+1
            if(i == levelNodes - 1)
            {
                result[*returnSize] = node->val;//结点数据入数组,行数加一
                result = (int*)realloc(result,(++currentlevel)*sizeof(int));//数组根据层数扩展
                (*returnSize)++;
            }

            //左右子树入队
            if (node->left) 
            {
                Queue_in(queue, node->left);
            }
            if (node->right) 
            {
                Queue_in(queue, node->right);
            }
        }
        
    }

    free(queue);
    return result;
}

TIPS:

这一题的综合型很强,包括了

①前序中序转换成二叉树(递归)

②将二叉树层序遍历(队列操作)

前面的几道题刷完后这题其实也不难

#TOP101#
TOP101-BM系列 文章被收录于专栏

系列的题解

全部评论

相关推荐

牛牛不会牛泪:可以先别急着租房,去青旅,或者订个近点的宾馆待几天。先看看要做的能不能学到东西,然后看文档完不完善,写的好不好,mentor对你咋样,公司氛围啥的。情况不对赶快跑路找下家
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务