1

题目大意:

给定N个结点的CBT的每一个结点的值,要求输出对应的层序遍历序列

算法思路:

首先明确CBT的概念,这里要求每一次尽可能的满,除了最后一层,这里的定义符合完全二叉树,那么我们可以对这颗完全二叉树按照层次遍历序列进行编号,这样便于输出层序遍历序列(可能现在还不明白,看到后面就好了),为了方便轻松获得左孩子和右孩子我们使用1来代表根节点的编号.然后对于给定结点数量N的完全二叉树,其层次序列的编号是固定的就是1,2,3...n,那么我们从1到n进行遍历,对于每一个结点i如果有左孩子$2*i<=n$,那么就更新左孩子编号$node[i].left = 2*i$,如果有右孩子$2*i+1<=n$,那么
就更新右孩子编号$node[i].right = 2*i+1$,并且初始化所有结点的左右孩子都为-1。接下来就是建树的过程,也是此题唯一的难点,我们知道二叉搜索树的中序遍历序列(数值)是有序的,那么我们将输入序列进行排序就可以得到中序遍历序列(数值),同样的,我们把存储该树的静态数组的下标也进行排序,这样就得到了中序遍历序列数组的下标和数值,将它们一一对应就可以获得这颗树了,可能现在还是不太明白,看下图就好了。
图片.png
图片.png
其主要操作就是使用了一个num数组存储输入的数据,对其进行排序后就是中序遍历序列,然后我们将一颗空树进行中序遍历,然后将值一一填入到结点中,就完成了树的创建。仔细观察就知道,CBT的层序遍历实际上就是静态数组按照顺序依次输出的结果。

提交结果:

图片.png

AC代码:

#include<cstdio>
#include<queue>
#include<algorithm>

using namespace std;

int N;
int num[1005];

struct Node{
    int data;
    int left;
    int right;
    Node(){
        left = right = -1;
    }
}node[1005];

int index = 1;// 中序序列指针 
void inTraverse(int root){
    if(root==-1) return;
    inTraverse(node[root].left);
    node[root].data = num[index++];
    inTraverse(node[root].right);
}

int main(){
    scanf("%d",&N);
    for(int i=1;i<=N;++i){
        scanf("%d",&num[i]);
        if(2*i<=N){
            // 有左孩子
            node[i].left = 2*i; 
        }
        if(2*i+1<=N){
            // 有右孩子
            node[i].right = 2*i+1; 
        }
    }
    // 将num数组进行排序获得树的中序遍历序列
    sort(num+1,num+N+1);
    // 中序遍历node,将num数组插入其中,根节点默认为1
    inTraverse(1); 
    // 输出层序遍历序列 
    for(int i=1;i<=N;++i){
        printf("%d",node[i].data);
        if(i<N) printf(" ");
    }
    return 0;
}

乔梓鑫
569 声望17 粉丝

主要分享个人学习经验和心得