数据结构第四天: Complete Binary Search Tree 【搜索二叉树,完全二叉树】

news2024/12/24 21:34:46

二叉搜索树 bst 被递归地定义为具有以下属性的二叉树

节点的左子树仅包含键小于节点键的节点
a 的右子树节点只包含键大于或等于节点键的节点
左右子树也必须是二叉搜索树
完全二叉树cbt是一棵完全充满可能异常的树从左到右填充的底层

现在给定一系列不同的非负整数键,如果要求树也必须是你认为的cbt,则可以构造一个唯一的bst输出此 bst 的层序遍历序列

输入规范
每个输入文件包含一个测试用例,每个案例第一行包含一个正整数 n ≤ 1000 然后 n 个不同的非负整数keys在下一行给出,一行中的所有数字用空格分隔,并且不大于2000

输出规范

 这道题需要的操作时排序并且需要遍历,最重要的一点它是个完全二叉树,所以数组是最适合的

这道题我的思路来自于浙江大学课件7.0.2完全二叉树

解题思路 

这道题说白就是将输入的样例构造成一个完全搜索二叉树。因为完全线索二叉树的根节点一定是是一个处于左右子树中间的那个值(搜索二叉树其根节点要比自己的左子树上所有节点都大又要比自己右子树上所有节点都小)然后我们的思路就是在排好序的样例上每次去找一下当前函数所在的树的根节点然后将其插入二叉搜索树对应的位置,然后直接输出即可,因为此时我们构建的树数组只要我们顺序遍历就是层序遍历。

int n;
    cin>>n;
    for(int i=0;i<n;i++){
        int a;
        cin>>a;
        tree[i] = a;
    }
    //对输入样例排序
    sort(tree,tree+n,compare);
    solve(0,n-1,0);
    for(int i=0;i<n-1;i++)
        cout<<Ttree[i]<<" ";
    cout<<Ttree[n-1];

那么solve函数(排好序的样例上每次去找一下当前函数所在的树的根节点然后将其插入二叉搜索树对应的位置)该咋写呢?我们的思路是这样的,我们入函数的一定是所有样例,那么我们就是找整个样例的根节点,我们又知道根节点一定是是一个处于左右子树中间的那个值,然后我们的数组又是从0开始存值的,所以说其实在样例数组中左子树的个数加上此时这个树的左边界就可以确定此时这个树的根节点的值在样例数组的位置。

//得出左边节点个数
    int L = GetLeftLength(n);
    //左子树的个数就是此根节点的下标
    Ttree[rootIndex] = tree[L + Aleft];

然后我们找到最大的树的根节点,我们就可以继续递归去找它的左子树和右子树的根节点。这样这个函数该解决的问题就解决了。

//此节点的左节点在完全二叉树的下标
    int leftRootIndex = rootIndex * 2 + 1;
    //此节点的右节点在完全二叉树的下标
    int rightRootIndex = leftRootIndex + 1;
    solve(Aleft,Aleft+L-1,leftRootIndex);
    solve(Aleft+L+1,Aright,rightRootIndex);

但是如何找每个树的左子树的个数呢?

我们可以根据上图推出一个完全二叉树完美的那部分总共的个数(N)为pow(2,这个树的高度)-1+这个树减去完美部分的节点个数(X),

 

 然后我们就可以通过上述的公式推出 树的高度(h)=log2(N+1-X) ,然后我们就可以通过这个算出X,(但是我们题目中需要算出的是左子树节点个数如下图是不满足L(左子树个数)=pow(2,h-1)-1+X1(左子树除了完美部分之外的个数)这个公式的,因为很可能右边也有节点)

(像这样的情况就不满足)

所以X1=min(X,左子树最大值(pow(2,h-1)))

然后就可以根据公式L(左子树个数)=pow(2,h-1)-1+X1写出函数。

int GetLeftLength(int n){
    //将完全二叉树完美的部分的高度求出,由2的h次方 -1 +x = n推出
    int h = log2(n+1);
    //求出左边除去完满二叉树部分多余的节点
    int x = n - pow(2,h) + 1;
    int a = pow(2,h-1);
    x = min(x,a);
    //多余的节点 + 完美二叉树左边一边的节点
    int L = a - 1 + x;
    return L;
}

下面是完整代码 

#include <iostream>
#include <cmath>
#include <algorithm>

using namespace std;
int compare(int a, int b){
    return a<b;
}
int tree[1001];
int Ttree[1001];
int GetLeftLength(int n){
    //将完全二叉树完美的部分的高度求出,由2的h次方 -1 +x = n推出
    int h = log2(n+1);
    //求出左边除去完满二叉树部分多余的节点
    int x = n - pow(2,h) + 1;
    int a = pow(2,h-1);
    x = min(x,a);
    //多余的节点 + 完美二叉树左边一边的节点
    int L = a - 1 + x;
    return L;
}
//后面的参数都是每次遍历时此时的树
//:Aleft:输入样例左边界,Aright:输入样例右边界,完全二叉树根节点下标
void solve(int Aleft,int Aright,int rootIndex){
    int n = Aright - Aleft + 1;
    // cout<<n<<endl;
    if(n==0) return;
    //得出左边节点个数
    int L = GetLeftLength(n);
    //左子树的个数就是此根节点的下标
    Ttree[rootIndex] = tree[L + Aleft];
    //此节点的左节点在完全二叉树的下标
    int leftRootIndex = rootIndex * 2 + 1;
    //此节点的右节点在完全二叉树的下标
    int rightRootIndex = leftRootIndex + 1;
    solve(Aleft,Aleft+L-1,leftRootIndex);
    solve(Aleft+L+1,Aright,rightRootIndex);
}
int main(){
    int n;
    cin>>n;
    for(int i=0;i<n;i++){
        int a;
        cin>>a;
        tree[i] = a;
    }
    //对输入样例排序
    sort(tree,tree+n,compare);
    solve(0,n-1,0);
    for(int i=0;i<n-1;i++)
        cout<<Ttree[i]<<" ";
    cout<<Ttree[n-1];
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/567076.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

5.25黄金是延续下跌还是强势反弹?今日如何布局

近期有哪些消息面影响黄金走势&#xff1f;今日黄金多空该如何研判&#xff1f; ​黄金消息面解析&#xff1a;周四(5月25日)亚市盘中&#xff0c;现报1957.89美元/盎司&#xff0c;昨日最高触及1985.28美元/盎司&#xff0c;最低触及1956.68美元/盎司。周三公布的会议纪要显示…

web自动化测试进阶篇03 ———自动化并发测试应用

&#x1f60f;作者简介&#xff1a;博主是一位测试管理者&#xff0c;同时也是一名对外企业兼职讲师。 &#x1f4e1;主页地址&#xff1a;【Austin_zhai】 &#x1f646;目的与景愿&#xff1a;旨在于能帮助更多的测试行业人员提升软硬技能&#xff0c;分享行业相关最新信息。…

选择小程序第三方开发框架时,需要考虑哪些因素?

在选择小程序第三方开发框架时&#xff0c;我们需要综合考虑开发者技术栈、项目需求和目标平台等因素。Taro 是一个多端统一开发框架&#xff0c;适合需要覆盖多个平台的开发者&#xff0c;最终的选择应该基于个人的技术背景和项目需求&#xff0c;同时也要关注框架的稳定性、社…

如何解决接口幂等性问题?

什么是幂等性&#xff1f; 参考地址&#xff1a;解决幂等问题 概念&#xff1a; 一个接口&#xff0c;不管我调多少次&#xff0c;只要参数不变&#xff0c;结果也应该不变。 但是在实际工作中&#xff0c;幂等性一般分为两种&#xff1a; 请求幂等&#xff1a;每次请求&…

Linux的学习

学习笔记&#xff0c;只写重点&#xff0c;不连贯&#xff0c;写得很水。 视频from:2021韩顺平 一周学会Linux。学习地址&#xff1a;https://www.bilibili.com/video/BV1Sv411r7vd 老师说明&#xff1a;后面我们的Redis、ginx包括项目都会使用到Linux,也是和我讲解的Linux版本…

开源网安受邀参加2023澳门万讯论坛,引领软件安全领域国产化替代浪潮

近日&#xff0c;2023万讯论坛在澳门成功举办。本次论坛由万讯电脑科技主办&#xff0c;旨在为澳门引入更多具有市场竞争力且自主研发的国内科技产品。开源网安作为拥有软件安全领域全链条产品的厂商&#xff0c;受邀参加本次论坛并分享软件安全领域国产化替代方案。 随着全球通…

Typescript ?问号的几种不同用法

1、作为Typescript 接口属性数量不确定时的定义方法 如果使用接口来限定了变量或者形参, 那么在给变量或者形参赋值的时候, 赋予的值就必须和接口限定的一模一样才可以, 多一个或者少一个都不行。 但是开发中我们往往可能会遇到少一个或者多一个的场景。 &#xff08;1&#…

Springboot +spring security,如何解决Session共享问题

一.简介 前一篇文章的所有的会话都是基于单机&#xff0c;如果服务部署在集群中&#xff0c;就会出现session失效的问题&#xff0c;为什么在集群环境下会出现session失效呢&#xff1f; 二.集群环境下session失效的原因 当用户第一次访问项目时&#xff0c;是机器1处理了登…

Kubernetes1.22.0 部署 metricis-service

概述 Install cfssl cat > proxy-client-csr.json<<EOF {"CN": "aggregator","hosts": [],"key": {"algo": "rsa","size": 2048},"names": [{"C": "CN",&quo…

SVD求解两组多维点之间的欧式变换矩阵,及halcon代码实现

之前研究了二维点的仿射变换&#xff0c;用解矩阵的方式求解了两组二维点之间的变换矩阵。 学习了下SVD&#xff0c;看到可以用SVD求解两组多维点之间的欧式变换矩阵&#xff0c;当然也是个最优化问题。 这里的变换只有平移和旋转&#xff0c;没有缩放。 一、先说结论&#…

【DNDC模型】农田生态、陆地生态系统的动态模拟模型

DNDC模型 DNDC模型是一个用于模拟和追踪农业生态系统中碳氮生物地球化学循环的过程模型&#xff0c;可以用来模拟农业生态系统碳氮排放、农作物产量、土壤固碳作用以及硝酸盐淋失等过程。 模型由两部分组成&#xff1a;第一部分包括土壤气候、植物生长和有机质分解等3个子模型…

整理6个超好用的在线编辑器!

随着 Web 开发对图像可扩展性、响应性、交互性和可编程性的需求增加&#xff0c;SVG 图形成为最适合 Web 开发的图像格式之一。它因文件小、可压缩性强并且无论如何放大或缩小&#xff0c;图像都不会失真而受到欢迎。然而&#xff0c;为了编辑 SVG 图像&#xff0c;需要使用 SV…

【共享内存】

1 共享内存示意图 共享内存区是最快的 IPC 形式。一旦这样的内存映射到共享它的进程的地址空间&#xff0c;这些进程间数据传递不再涉及到 内核&#xff0c;换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据。 2 共享内存数据结构 struct shmid_ds {struct ipc_…

Mysql 学习(十 三)InnoDB的BufferPool

为什么要有缓存&#xff1f; 我们知道每次获取数据我们都需要从磁盘获取&#xff0c;磁盘的运行速度又慢的不行&#xff0c;对于这一个问题我们要怎么解决呢&#xff1f;我们把查询结果存储起来不就行了&#xff0c;因为当需要访问某个页的数据时&#xff0c;就会把完整的页的…

再见SpringSecurity,比Shiro更简单优雅的轻量级Sa-Token框架我粉了

1. 技术选型 最近在做登录、授权的功能&#xff0c;一开始考虑到的是spring boot spring security&#xff0c;但spring security太重&#xff0c;而我们是轻量级的项目&#xff0c;所以&#xff0c;spring security不适合我们。 而后考虑spring boot shiro&#xff0c;但s…

SSD202 Linux开发日志记录

一、挂载U盘 SDK默认自动加载USB存储模块&#xff0c;但没有自动挂载&#xff0c;插上U盘后识别sda mount /dev/sda /mnt/即可在/mnt查看U盘文件 二、make & make menuconfig提示失败 打开新终端后输入 declare -x ARCH"arm" declare -x CROSS_COMPILE"…

记一次php 导出word文档

导出试卷 先看效果 $paper Exam::where(id, $data[examid])->field(paper_id,title)->find();$bankIds PaperStorehouse::where(id, $paper[paper_id])->value(banks);$field type,rate,name,options,parsing,value,question_id,parsing_id;$bankInfo Banks::whe…

北邮22信通:二叉树显示路径的两种方法 递归函数保存现场返回现场的实例

北邮22信通一枚~ 跟随课程进度每周更新数据结构与算法的代码和文章 持续关注作者 解锁更多邮苑信通专属代码~ 获取更多文章 请访问专栏~ 北邮22信通_青山如墨雨如画的博客-CSDN博客 一.讲解 要想实现二叉树的路径显示&#xff0c;我们要按照…

gitbook在centos上安装

1&#xff09;官网下载Node.js的Linux64位的二进制包:Download | Node.js 或者在线下载&#xff1a; wget https://nodejs.org/dist/v12.16.1/node-v12.16.1-linux-x64.tar.xz ​​2)到指定目录​解压 cd /opt/gitbook tar -xJf node-v12.16.1-linux-x64.tar.xz mv node-…

记录--按钮级别权限怎么控制

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 最近的面试中有一个面试官问我按钮级别的权限怎么控制&#xff0c;我说直接v-if啊&#xff0c;他说不够好&#xff0c;我说我们项目中按钮级别的权限控制情况不多&#xff0c;所以v-if就够了&#xff…