LeetCode·987.二叉树的垂直遍历·桶排序·模拟

链接:https://leetcode.cn/problems/vertical-order-traversal-of-a-binary-tree/solution/chun-c-by-xun-ge-v-7x1f/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 

题目

 

示例

 

思路

解题思路
设计算法实现二叉树的 垂序遍历 序列。
模拟法

按照题目给定要求,模拟每个步骤实现。


对树相关的问题,递归肯定是跑不了。

  • 因为树这种数据结构我们并不好直接操作每一个元素,而且上下元素的访问也不方便,所以我们申请一个结构体数组,递归调用每一个树节点,保存对应的元素值和下标

typedef struct nums{
    int left;//水平下标
    int right;//垂直下标
    int val;//树节点值
}nums; 

  • 然后根据题目要求,构造垂序遍历序列将对应元素填入即可,这里可以使用桶排序对结构体数组进行简单的处理,方便构造时减少工作量


具体实现看代码 

代码

/**
 * 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().
 */
typedef struct nums{//结构体
    int left;//水平下标
    int right;//垂直下标
    int val;//树节点值
}nums; 
//递归遍历每一个树节点
void dfs(struct TreeNode * root, int * inode, nums * ans, int left, int right)
{
    if(root == NULL)
    {
        return;
    }
    ans[(*inode)].val = root->val;//保存对应值和下标
    ans[(*inode)].left = left;
    ans[(*inode)].right = right;
    (*inode)++;
    dfs(root->left, inode, ans, left - 1, right + 1);//遍历左子节点
    dfs(root->right, inode, ans, left + 1, right + 1);//遍历右子节点
    return;
}
//用于结构体的三级排序
int cmp(const nums* a, const nums* b) {
    // 先排left,再排right,最后排val
    if (a->left != b->left) {
        return a->left - b->left;
    } else if (a->right != b->right){
        return a->right - b->right;
    } else {
        return a->val - b->val;
    }
}
int** verticalTraversal(struct TreeNode* root, int* returnSize, int** returnColumnSizes){
    nums ans[1001];//申请结构体数组
    int inode = 0;//初始化结构体下标
    dfs(root, &inode, ans, 0, 0);//更新结构体
    qsort(ans,inode,sizeof(struct nums),cmp);//排序
    int n = ans[inode-1].left - ans[0].left + 1;//确定垂序遍历序列的行数
    int ** res = malloc(sizeof(int *) * n);//申请空间
    *returnSize = n;
    *returnColumnSizes = malloc(sizeof(int) * n);

    int l = 0;
    int inod = 0;
    int i = 0;
    ans[inode++].left = INT_MAX;//构造一个坏点,使最后一个元素可以被访问
    for(i = 0; i < inode-1; i++)//遍历结构体数组
    {
        
        if(ans[i].left == ans[i+1].left)//是同一水平下标
        {
            continue;
        }
        int max = i - l + 1;//不是同一水平下标了,存入垂序遍历序列
        res[inod] = malloc(sizeof(int) * max);//初始化垂序遍历序列的列长
        (*returnColumnSizes)[inod] = max;
        int j = 0;
        while(l <= i && j < max)//存入垂序遍历序列
        {
            res[inod][j++] = ans[l].val;//直接存就好了,因为快速排序的时候,已经对数组进行处理了
            l++;
        }
        inod++;
    }
    return res;
}


时间空间复杂度

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值