• 笛卡尔树(暑假每日一题 9)


    笛卡尔树 是由一系列不同数字构成的二叉树。

    树满足堆的性质,中序遍历返回原始序列。
    最小笛卡尔树表示满足小根堆性质的笛卡尔树。

    例如,给定序列 { 8 , 15 , 3 , 4 , 1 , 5 , 12 , 10 , 18 , 6 } \{8,15,3,4,1,5,12,10,18,6\} {8,15,3,4,1,5,12,10,18,6},则生成的最小堆笛卡尔树如图所示。

    在这里插入图片描述

    现在,给定一个长度为 N N N 的原始序列,请你生成最小堆笛卡尔树,并输出其层序遍历序列。

    输入格式
    第一行包含整数 N N N

    第二行包含 N N N 个两两不同的整数,表示原始序列。

    输出格式
    共一行,输出最小堆笛卡尔树的层序遍历序列。

    数据范围
    1 ≤ N ≤ 30 , 1≤N≤30, 1N30,
    原始序列中元素的取值范围 [ − 2147483648 , 2147483647 ] [−2147483648,2147483647] [2147483648,2147483647]

    输入样例:

    10
    8 15 3 4 1 5 12 10 18 6
    
    • 1
    • 2

    输出样例:

    1 3 5 8 4 6 15 10 12 18
    
    • 1

    • 根据小根堆的性质,当前子树的根节点是当前区间元素中最小的,且中序遍历结果为原序列可以得出,根节点左边的元素是当前节点的左子树,右边的元素是当前节点的右子树。
    • 递归实际上是一种前序遍历,所以可以将当前元素加入 层数为 d 的数组中,然后再依次遍历每层的数组,遍历结果为层序遍历结果。

    不用 bfs

    #include
    #include
    
    using namespace std;
    
    const int N = 40;
    
    int n;
    int w[N];
    vector<int> level[N];
    
    int getmin(int l, int r){
        
        int res = l;
        for(int i = l; i <= r; i++)
            if(w[res] > w[i]) res = i;
            
        return res;
    }
    
    void dfs(int l, int r, int d){
        
        if(l > r) return;
        
        int root = getmin(l, r);
        level[d].push_back(w[root]);
        
        dfs(l, root - 1, d + 1);
        dfs(root + 1, r, d + 1);
    }
    
    int main(){
        
        cin >> n;
        for(int i = 0; i < n; i++)
            cin >> w[i];
        
        dfs(0, n - 1, 0);
        
        for(int i = 0; level[i].size(); i++)
            for(int j = 0; j < level[i].size(); j++)
                cout << level[i][j] << ' ';
        
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    用bfs

    #include
    #include
    
    using namespace std;
    
    const int N = 40;
    
    int n;
    int q[N];
    int w[N], L[N], R[N];
    vector<int> level[N];
    
    int getmin(int l, int r){
        
        int res = l;
        for(int i = l; i <= r; i++)
            if(w[res] > w[i]) res = i;
            
        return res;
    }
    
    int dfs(int l, int r){
        
        if(l > r) return -1;
        
        int root = getmin(l, r);
        
        L[root] = dfs(l, root - 1);
        R[root] = dfs(root + 1, r);
        
        return root;
    }
    
    void bfs(int root){
        
        int hh = 0, tt = 0;
        q[0] = root;
        
        while(hh <= tt){
            
            int u = q[hh ++];
            if(L[u] != -1) q[++tt] = L[u];
            if(R[u] != -1) q[++tt] = R[u];
        }
        
        for(int i = 0; i <= tt; i++)
            cout << w[q[i]] << ' ';
    }
    
    int main(){
        
        cin >> n;
        for(int i = 0; i < n; i++)
            cin >> w[i];
        
        int root = dfs(0, n - 1);
        bfs(root);
        
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
  • 相关阅读:
    spring_代理模式_学习笔记
    mysql实战45讲【2】一条sql更新语句是如何执行的
    MySQL知识点补充
    HTB靶场之Sandworm
    Java—数组中涉及的常见算法
    shell_74.Linux创建使用函数
    2).基础平台与业务实现规范
    解决Map序列化成JSON字符串传给前端后属性乱序问题
    c++STL库
    python循环时循环体一会多一会少,这个思路值得参考
  • 原文地址:https://blog.csdn.net/qq_46456049/article/details/126050072