zoukankan      html  css  js  c++  java
  • 数组二叉树

    要求:

    现给一串数字,按照顺序从根插入到二叉树中。但是插入的过程要注意,左子树的值要小于等于父节点,右子树的值要大于父节点。

    例如,序列为1 3 4 2 3 0,插入对应的二叉树为

                          1

                       /       

                     0            3

                                 /     

                               2         4

                                

                                  3

    建好二叉树后,从根开始输出每行数字,每层按照从左到右的顺序输出。

    输入:

    第一行为数字序列长度N(1≤N≤11)

    接下来n个数字,每个数字大于等于0

    输出:

    整棵二叉树的数字。每个数字一个换行

    样例输入:

    1 3 4 2 3 0

    样例输出:

    0

    2

    3

    Hint:父节点的位置为i时,左子节点为i*2+1,右子节点为i*2+2.

     

    先解释一下数组如何表示二叉树:

    一个数组为a[10],那么它表示的完全二叉树为(下面数字只表示数组下标,不表示数组的值)

                                              0

                                          /         

                                        1             2

                                     /              /    

                                   3         4      5      6

                                /          /   

                               7      8   9

    这就是一个数组表示的完全二叉树。

    完全二叉树就是除了最下面那一层外(这个图是第四层7 8 9)前面几层是满二叉树(度(子节点数)为0或2)

    也就是说,我们用数组表示二叉树时,并不需要对数组进行什么操作,

    只是我们意识上认为这个数组是个二叉树,然后按照二叉树来处理这个数组。

    也就是数组下标遵循二叉树的规律。就比如左右子树和父节点的关系。

    虽然说我们这道题结果不是完全二叉树,就像例题那样,

    但是我们可以把它想像成值全为-1的完全二叉树,然后向-1的节点插入值。

    思路分析:

    由提示可以看出,这就像是一个哈希查找(按照一定规则映射到数组)

    这个规则就是左子树小于等于父节点,右子树大于父节点。

    而父节点和左右子树下标的关系值已经给了出来。

    而节点的值非负,所以我们可以将目标数组全部赋为-1,以此来判断目标数组是否存有值。

    所以这道题本质就是向空数组插入数据的过程。

    输出的时候,我们需要的是值不为-1的节点

    (我们创建了这个数组,按照提示的规则插入数据,其实就是把数组当成了完全二叉树)

    所以按照我们插入的结果,按数组下标输出就行。

    详细代码如下。(若结果出错,可能是target数组开的不够大)

     1  1 #include<bits/stdc++.h>
     2  2 using namespace std;
     3  3 int main()
     4  4 {
     5  5     int n;
     6  6     cin>>n;
     7  7     int a[n];       //写入数据的数组
     8  8     for (int i = 0; i < n; i++) cin>>a[i];
     9  9     int target[100];     //空数组,用来接受映射结果
    10 10     target[0]=a[0];      //树根是第一个位置
    11 11     for (int i = 1; i < 100; i++) target[i]=-1;  //因为a[n]大于等于零
    12 12     //所以我们可以把其他的数都赋为-1,来区分数组这个位置有没有存数
    13 13     for (int i = 1; i < n; i++)   //这里开始插入
    14 14     {
    15 15         int j=0;                 //从树根开始找位置
    16 16         while(target[j]!=-1)     //不等于-1的话说明这个位置已经插入数字了
    17 17         {
    18 18             if (a[i]<=target[j])    j=2*j+1; //判断大小,(小于等于父节点)检查左子树有没有插入
    19 19             else j=2*j+2;                   //检查右子树
    20 20         }
    21 21         target[j]=a[i];           //找到位置后,赋值
    22 22     }
    23 23     int j=0;                     //开始从头开始找插入的数字
    24 24     for (int i = 0; i < n; i++)  //数组大小为n,所以找到n个即可
    25 25     {
    26 26         while (target[j]==-1) j++; //说明这个位置是空的,继续找
    27 27         cout<<target[j]<<endl;   //退出循环,说明找到了,把数字输出来
    28 28         j++;                    //输出之后,继续找,所以j要递增
    29 29     }
    30 30     return 0;
    31 31 }
  • 相关阅读:
    【t090】吉祥数
    【u221】分数
    【u212】&&【t036】最大和
    【u125】最大子树和
    【u124】环状最大两段子段和
    【u123】最大子段和
    【u122】迎接仪式
    【u121】教主的花园
    【u118】日志分析
    【u117】队列安排
  • 原文地址:https://www.cnblogs.com/Arthas8086/p/12095005.html
Copyright © 2011-2022 走看看