|CBT|1064 Complete Binary Search Tree (30分)???用数组存储_数组下标(1)就是节点编号_数组元素的值就是节点点权

这篇博客介绍了如何利用完全二叉树的特性构建二叉搜索树,并通过中序遍历的方法填充数组以实现树的构建。之后,通过层序遍历输出构建好的完全二叉搜索树的序列。文章提供了C++代码示例,展示了解决此类问题的具体步骤和方法。
摘要由CSDN通过智能技术生成

https://blog.csdn.net/sinat_41144773/article/details/89530403
在这里插入图片描述

完全二叉树:
对于完全二叉树来说,除了采用二叉链表存储结构外,
还可以有更方便的存储方法
对一棵完全二叉树,如果给它的所有节点从上到下、从左到右的顺序进行编号(从1开始)
就会得到下图的编号顺序
在这里插入图片描述

对完全二叉树的任何一个节点(设编号为x),其左孩子的编号一定是2x,而右孩子的编号一定是2x+1。

也就是说,完全二叉树可以通过建立一个大小为2^k的数组来存放所有节点的信息
其中k是完全二叉树的最大高度,且1号为存放的必须是根节点(这样就可以用数组的下表来表示节点编号,且左右孩子都可以直接通过计算得到)
在这里插入图片描述

该数组中元素存放的顺序恰好为该完全二叉树的层序遍历序列

判断某个节点是否是叶子节点的标志:该节点(记下标为root)的左子节点的编号为root*2大于总结点个数n

判断某个节点是否是空节点的标志:该节点下标root大于节点总个数n
题目大意:给你一个序列,所有的数都非负且不同,然后要求你用这个序列建一个完全二叉搜索树,再给出这个树的层序序列。

解题思路:
1.我们知道,二叉搜索树的中序序列是有序的,那么我们把输入的序列进行排序,就得到了这棵BST的中序序列,
2.我们再按中序遍历的方式建树,就得到了这棵完全二叉搜索树,因为是完全二叉树,所以可以用一个数组来保存,且有n个结点,就一定会把前面n个空间占满。
3.最后输出层序序列的时候,在vector中从头到尾输出就是层序序列,因为在类array结构中存储树,总是把根节点存储在第一个,子树的根节点必然也是在子树之前。

我们一般通过中序+前序/后序进行建树

这次有中序,我们自然想到了建树

1.如果使用数组来存放完全二叉树,那么对完全二叉树当中的任何一个结点(设编号为x,根节点编号为1),其左孩子结点的编号为2x,右孩子结点编号为2x+1。则可以开一个数组CBT[maxn],其中CBT[1]~CBT[N]按层序存放完全二叉树的N个结点,这个数组就存放了,一颗没有对其元素进行赋值的完全二叉树。
2.二叉排序树中序遍历序列是递增的,所以将输入的数字从小到大排序,然后对CBT数组表示的二叉树进行中序遍历,并在遍历过程中将数字从小到大填入数组,最后就能得到一颗完全二叉排序树。
3.CBT数组是按二叉树的层序存放结点的,因此将数组元素按顺序输出即为层序遍历序列。

在这里插入图片描述

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;

vector<int> v1;
int n,index=0,CBT[1010];

void inOrder(int root){//中序//左根右
    if(root>n)return;
    inOrder(2*root);//左
    //第一次找到最左边的左孩子节点的父亲节点,给这个父亲节点赋值
    CBT[root]=v1[index++];//根//v1是按照从小到大排序的//0123456789//root是下标啊
    inOrder(2*root+1);//右
    
}

int main()
{
    cin>>n;
    for(int i=0;i<n;i++){
        int node_id;
        cin>>node_id;
        v1.push_back(node_id);
    }
    sort(v1.begin(),v1.end());//升序,从小到大//---bst的中序
    //通过bst的中序序列进行建树
    inOrder(1);//遍历也能拿来建树啊
    for(int i=1;i<=n;i++){
        printf("%d",CBT[i]);
        if(i<n)printf(" ");
    }
    return 0;
}

----
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;

int n,index=0;
int node[1010],CBT[1010];

void inOrder(int root){//节点编号
    if(root>n)return;
    inOrder(2*root);
    CBT[root]=node[index++];//先找最左边的节点--赋值---中序遍历(左根右)---bst中序_最左边最小
    inOrder(2*root+1);
}

int main()
{
    cin>>n;
    for(int i=0;i<n;i++){
        scanf("%d",&node[i]);
    }
    sort(node,node+n);
    inOrder(1);//数组下标
    //完全二叉树的层序遍历就是数组存储的那般
    for(int i=1;i<=n;i++){
        if(i==1)cout<<CBT[i];
        else cout<<" "<<CBT[i];
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值