代码随想录算法训练营第十四天 | 二叉树 part02 | 层序遍历

层序遍历

思路

代码随想录算法训练营第十四天 | 二叉树 part02 | 层序遍历_第1张图片

问题是,C语言没有队列结构,

其实只要创建一个足够大的数组,维护队列的头和尾索引,就能做到类似队列的东西

leetcode 题库 102. 二叉树的层序遍历

为例写个层序遍历模板

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */
int** levelOrder(struct TreeNode* root, int* returnSize, int** returnColumnSizes){
    int** ret = (int**)malloc(sizeof(int*) * 2000); 
    struct TreeNode* queue[2001];
    int columnSizes[2000];
    int head = 0, tail = 0, start, i, len;

    *returnSize = 0;
    if(root != NULL)
    {
        queue[tail++] = root;
    }

    while(head != tail)
    {
        /* 为该层创建数组 */
        ret[*returnSize] = (int*)malloc(sizeof(int) * (tail - head));
        columnSizes[*returnSize] = tail - head;

        /* 处理该层结果,将下一层节点入队列 */
        start = head;
        head = tail;
        for(i = start; i < head; i++)
        {
            ret[*returnSize][i - start] = queue[i]->val;
            if(queue[i]->left != NULL)
            {
                queue[tail++] = queue[i]->left;
            }
            if(queue[i]->right != NULL)
            {
                queue[tail++] = queue[i]->right;
            }
        }
        (*returnSize)++;
    }
    /* 所有层遍历完了才知道有多少层 */
    *returnColumnSizes = (int*)malloc(sizeof(int) * (*returnSize));
    for(i = 0; i < (*returnSize); i++)
    {
        (*returnColumnSizes)[i] = columnSizes[i];
    }
    return ret;
}

199.二叉树的右视图

题目来源:leetcode 题库 199. 二叉树的右视图

给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。

思路

层序遍历中只保存每一层的最后一个节点即可

代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */


/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* rightSideView(struct TreeNode* root, int* returnSize){
    int rightValue[100];
    struct TreeNode* queue[100];
    int head = 0, tail = 0, start, i;
    int* ret;

    *returnSize = 0;
    if(root != NULL)
    {
        queue[tail++] = root;
    }

    while(head != tail)
    {
        start = head;
        head = tail;
        for(i = start; i < head; i++)
        {
            if(queue[i]->left != NULL)
            {
                queue[tail++] = queue[i]->left;
            }
            if(queue[i]->right != NULL)
            {
                queue[tail++] = queue[i]->right;
            }
            if(i == (head - 1))
            {
                rightValue[*returnSize] = queue[i]->val;
            }
        }
        (*returnSize)++;
    }
    ret = (int*)malloc(sizeof(int)*(*returnSize));
    for(i = 0; i <(*returnSize); i++)
    {
        ret[i] = rightValue[i];
    }
    return ret;
}

107.二叉树的层次遍历 II

题目来源:leetcode 题库 107. 二叉树的层次遍历 II

给你二叉树的根节点 root ,返回其节点值 自底向上的层序遍历 。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)

思路

相比于普通层序遍历,只是把结果翻转一下

正常层序遍历之后,使用双指针翻转结果指针数组以及长度数组

代码

    head = 0;
    tail = (*returnSize) - 1;
    while(head < tail)
    {
        temp = ret[head];
        ret[head] = ret[tail];
        ret[tail] = temp;
        start = (*returnColumnSizes)[head];
        (*returnColumnSizes)[head] = (*returnColumnSizes)[tail];
        (*returnColumnSizes)[tail] = start;
        head++;
        tail--;
    }

代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */


/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */
int** levelOrderBottom(struct TreeNode* root, int* returnSize, int** returnColumnSizes){
    int** ret = (int**)malloc(sizeof(int*) * 2000); 
    struct TreeNode* queue[2001];
    int columnSizes[2000];
    int head = 0, tail = 0, start, i;
    int* temp;

    *returnSize = 0;
    if(root != NULL)
    {
        queue[tail++] = root;
    }

    while(head != tail)
    {
        /* 为该层创建数组 */
        ret[*returnSize] = (int*)malloc(sizeof(int) * (tail - head));
        columnSizes[*returnSize] = tail - head;

        /* 处理该层结果,将下一层节点入队列 */
        start = head;
        head = tail;
        for(i = start; i < head; i++)
        {
            ret[*returnSize][i - start] = queue[i]->val;
            if(queue[i]->left != NULL)
            {
                queue[tail++] = queue[i]->left;
            }
            if(queue[i]->right != NULL)
            {
                queue[tail++] = queue[i]->right;
            }
        }
        (*returnSize)++;
    }
    /* 所有层遍历完了才知道有多少层 */
    *returnColumnSizes = (int*)malloc(sizeof(int) * (*returnSize));
    for(i = 0; i < (*returnSize); i++)
    {
        (*returnColumnSizes)[i] = columnSizes[i];
    }

    head = 0;
    tail = (*returnSize) - 1;
    while(head < tail)
    {
        temp = ret[head];
        ret[head] = ret[tail];
        ret[tail] = temp;
        start = (*returnColumnSizes)[head];
        (*returnColumnSizes)[head] = (*returnColumnSizes)[tail];
        (*returnColumnSizes)[tail] = start;
        head++;
        tail--;
    }
    return ret;
}

226.翻转二叉树

题目来源: leetcode 题库 226. 翻转二叉树

 给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。

思路

遍历二叉树的每个节点,翻转其左右节点即可

前序后序遍历都可以

代码

 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

struct TreeNode* invertTree(struct TreeNode* root){
    if(root == NULL)
    {
        return NULL;
    }

    struct TreeNode* temp;
    temp = root->left;
    root->left = root->right;
    root->right = temp;

    root->left = invertTree(root->left);
    root->right = invertTree(root->right);;
    return root;
}

101. 对称二叉树

题目来源:leetcode 题库 101. 对称二叉树

 给你一个二叉树的根节点 root , 检查它是否轴对称。

 思路

若一个二叉树是对称的,其对称的位置上的两个节点的子二叉树也是对称的,即

根节点的左子节点和右子节点就是对称的;

根节点的左子节点的左子节点与根节点的右节点的右节点是对称的,根节点的左子节点的右子节点与根节点的右子节点的左子节点是对称的。

类推...

因此判断左右两个个节点是否是对称的,除了判断两个节点的值相同外,还要判断左节点的左子节点与右节点的右子节点是否对称,左节点的右子节点与右节点的左子节点是否对称

代码

递归回溯

bool subisSymmetric(struct TreeNode* leftNode, struct TreeNode* rightNode)
{
    bool ret = true;;
    if((leftNode == NULL) && (rightNode == NULL))
    {
        
    }
    else if(((leftNode == NULL) && (rightNode != NULL)) ||
        ((leftNode != NULL) && (rightNode == NULL)) ||
        ((leftNode->val != rightNode->val)))
    {
        ret = false;
    }
    else
    {
        ret = subisSymmetric(leftNode->left, rightNode->right);
        if(ret == true)
        {
            ret = subisSymmetric(leftNode->right, rightNode->left);
        }
    }
    return ret;
}

bool isSymmetric(struct TreeNode* root){
    return subisSymmetric(root->left, root->right);
}

你可能感兴趣的:(代码随想录算法训练营,数据结构)