数据结构:构建完全二叉查找树

文章目录

    • 1、步骤 1: 对给定数组排序
    • 2、步骤 2: 递归构建完全二叉查找树
    • 3、注意
    • 4、在有序数组中寻找根结点位置
    • 5、代码实现
    • 6、其他方法?
      • 基本思路
      • 插入操作
      • 删除操作
      • 特别考虑

  对于一个给定序列的二叉查找树,有很多种,但是完全二叉查找树只有一种,因为树形是确定的,我们按照中根序列遍历的顺序也是按照数值大小顺序的,因此 按照树结点的中根遍历顺序 将 序列按照数值大小顺序 填入这颗树形确定的完全二叉树中,可以得到一颗唯一确定的完全二叉树。并且对于根结点,其左子树的所有结点都小于根结点,右子树的所有结点都大于等于根结点。
  构建一颗 完全二叉查找树(Complete Binary Search Tree,CBST)的算法关键在于如何保证二叉树的完全性质,同时维护二叉查找树(BST)的特性:对于任意节点,其左子树的所有节点的值小于该节点的值,其右子树的所有节点的值大于等于该节点的值。

以下是构建完全二叉查找树的一种有效算法:

1、步骤 1: 对给定数组排序

由于二叉查找树的中序遍历结果是一个有序数组,**首先要对输入的无序数组进行排序。**根结点的位置是可以唯一确定的。

2、步骤 2: 递归构建完全二叉查找树

  1. 选择中间元素作为树的根:从排序好的数组中选择中间的元素作为二叉查找树的根节点。如果有两个中间元素,选择它们中的任意一个。
  2. 递归构建左子树和右子树:将根节点左侧的元素递归地构建成左子树,将根节点右侧的元素递归地构建成右子树。

3、注意

  • 完全二叉树的定义是除了最后一层外,每一层都是完全填满的,而最后一层从左向右填充。上述算法构建的是一棵高度平衡的二叉查找树,但不一定满足完全二叉树的严格定义。构建满足完全二叉树定义的二叉查找树需要更复杂的逻辑来确保所有层(除了可能的最后一层)都完全填满。
  • 确保完全性的一个方法是通过计算给定元素数量所能构建的完全二叉树的最大高度,然后在构建过程中控制树的形态,使其满足完全二叉树的性质。

4、在有序数组中寻找根结点位置

在这里插入图片描述

完全二叉树的性质:

  • 性质的数学公式换算:
    • 树的结点个数n 取对数 可以得到树高: Treeheight=log2(n)
    • 通过树高 可以得到 除最后一层之外的右子树结点个数:rightTree1=pow(2,Treeheight-1)-1
    • 通过树高 以及 树的结点个数 可以得到树的最后一层结点个数:lastLevelNodes=n-(pow(2,Treeheight)-1)
    • 最后可以得到 右子树结点个数:rightTree=rightTree1+((lastLevelNodes-pow(2,Treeheight-1))>0?(lastLevelNodes-pow(2,Treeheight-1)) :0)
  • 直接求满了的层的总结点个数:
    • 利用快速幂思想,即取出总结点数n的二进制位数的最高位。
    • 然后计算即可得到右子树的个数

5、代码实现

  • 数学性质
#include<bits/stdc++.h>
using namespace std;struct TreeNode {int val;TreeNode *left, *right;TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};// 构建完全二叉查找树
TreeNode* createTree(int start, int end, vector<int>& sortedValues) {if (start > end) return nullptr;// 计算完全二叉树的最后一层前的所有节点数和最后一层的节点数int totalNodes = end - start + 1;int fullLevels = log2(totalNodes + 1);int lastLevelNodes = totalNodes - (pow(2, fullLevels) - 1);int leftSubtreeNodes = pow(2, fullLevels - 1) - 1 + min((int)pow(2, fullLevels - 1), lastLevelNodes);// 根据左子树的节点数确定根节点int rootIndex = start + leftSubtreeNodes;TreeNode* root = new TreeNode(sortedValues[rootIndex]);root->left = createTree(start, rootIndex - 1, sortedValues);root->right = createTree(rootIndex + 1, end, sortedValues);return root;
}// 层次遍历
void traversal(TreeNode* root) {if (!root) return;queue<TreeNode*> q;q.push(root);while (!q.empty()) {TreeNode* current = q.front(); q.pop();cout << current->val << " ";if (current->left) q.push(current->left);if (current->right) q.push(current->right);}
}int main() {int n;cin >> n;vector<int> values(n);for (int& value : values) {cin >> value;}sort(values.begin(), values.end());TreeNode* root = createTree(0, n - 1, values);traversal(root);return 0;
}
  • 直接计算
#include<bits/stdc++.h>
using namespace std;
struct TreeNode{TreeNode * left=nullptr;TreeNode * right=nullptr;int val;TreeNode (int v=0):val(v) {}
};
TreeNode * createTree(int left,int right,vector<int> & baby){//O(nlogn)if(left>right) return nullptr;if(left==right) return new TreeNode(baby[left]);TreeNode * root=nullptr;int flag=right-left+2;int b=1;while(flag!=1){//O(logn) 每次建树logn,n个结点共nlognb*=2;flag>>=1;}int rightTree_size=b/2-1;if(rightTree_size+2-b-b/2>0){rightTree_size+=rightTree_size+2-b-b/2;}root=new TreeNode(baby[right-rightTree_size]);root->left=createTree(left,right-rightTree_size-1,baby);root->right=createTree(right-rightTree_size+1,right,baby);return root;
}
int main(void){ios_base::sync_with_stdio(false);cin.tie(0);int n;cin>>n;vector<int> baby;for(int i=0;i<n;++i){int j;cin>>j;baby.emplace_back(j);}sort(baby.begin(),baby.end());//O(nlogn)createTree(0,n-1,baby);return 0;
}

6、其他方法?

动态构建完全二叉查找树(CBST)比静态构建更为复杂,因为需要在插入和删除操作发生时持续保持树的完全二叉树性质。一种方法是在每次插入或删除后重建树,但这显然效率不高。另一种思路是通过维护额外的信息和采用特定的插入/删除策略来尽可能保持树的完全性。下面是一个较为高效的动态构建完全二叉查找树的策略:

基本思路

动态维护一个完全二叉查找树,主要挑战在于插入和删除操作。对于插入操作,需要找到树中最后一个节点并在适当的位置插入新节点以保持完全二叉树的性质。对于删除操作,则需要找到可以替换被删除节点的节点(通常是树中的最后一个节点)并调整树以保持其完全性质。

插入操作

  1. 计算完全二叉树的深度:基于树当前的节点数量,可以计算出树的深度。
  2. 定位插入点:根据完全二叉树的性质,新节点应当被插入为最后一个节点。可以通过深度和节点数定位到这个位置。
  3. 执行插入:在定位到的位置插入新节点。如果需要,调整树的结构以保持二叉查找树的性质。

删除操作

  1. 定位并删除目标节点:找到需要删除的节点,将其删除。如果这个节点不是最后一个节点,则需要找到最后一个节点。
  2. 用最后一个节点替换删除的节点(如果被删除的节点不是最后一个节点):将最后一个节点移动到被删除节点的位置。
  3. 调整树:可能需要对树进行调整,以保持二叉查找树的性质。

特别考虑

  • 这种方法要求你能快速定位到树的最后一个节点,这可能需要维护额外的信息,如每层的节点数。
  • 插入和删除操作可能导致需要重新平衡树,以保持二叉查找树的性质。
  • 动态维护完全二叉树的复杂度主要在于定位最后一个节点和维护二叉查找树的性质。

动态地维护一个完全二叉查找树在实践中较为罕见,因为它要求在每次操作后都严格保持完全二叉树的性质,这可能导致较高的复杂性和成本。通常,人们会使用其他类型的自平衡二叉搜索树(如AVL树、红黑树)来获得较好的平均性能,尽管这些树不保证完全性质。

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

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

相关文章

【网站项目】医院核酸检测预约挂号小程序

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

4.1-4.5算法刷题笔记(17道题)

4.1-4.5算法刷题笔记 1. 区间和2. 区间合并3. 用队列实现栈&#xff08;queueMain queueTemp;&#xff09;4. 最小栈 1. 单链表模板5. 单链表 2. 双链表模板6. 双链表 3. 模拟栈7. 模拟栈(一个数组即可)8. 表达式求值 4. 队列 tt -1,hh 0;9. 模拟队列 5. 单调栈10. 单调栈 6…

【接口自动化】参数化替换

在做接口测试时&#xff0c;除了测单个接口&#xff0c;还需要进行业务链路间的接口测试 比如[注册-登陆]需要token鉴权的业务流 当我们用使用postman/jmeter等工具时&#xff0c;将注册接口的一些响应信息提取出来&#xff0c;放到登陆接口的请求中&#xff0c;来完成某个业务…

在Gazebo中如何拯救翻车的机器人

Gazebo提供了一些交互工具&#xff0c;允许你直接通过图形界面操作模型&#xff1a; 启动Gazebo后&#xff0c;在右侧工具栏中&#xff0c;你会找到一个可以拖拽物体的图标&#xff08;通常是一个手掌图标或者类似的&#xff09;。点击这个图标。 随后&#xff0c;你可以用鼠标…

Linux/Lame

Lame 今天随便乱逛发现这台机器貌似是 HackTheBox 平台的第一台机器&#xff0c;而且我还没做过&#xff0c;从简介上来看的话是一台很简单的机器&#xff0c;快快的玩一下 Enumeration nmap 首先用 nmap 扫描一下常见的端口&#xff0c;发现系统对外开放了 21,22,139,445 端…

面试算法-160-合并两个有序链表

题目 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4] 解 class Solution {public ListNode mergeTwoLists(ListNode li…

NineData创始人CEO叶正盛受邀参加『数据技术嘉年华』的技术大会

4月13日&#xff0c;NineData 创始人&CEO叶正盛受邀参加第13届『数据技术嘉年华』的技术大会。将和数据领域的技术爱好者一起相聚&#xff0c;并分享《NineData在10000公里跨云数据库间实时数据复制技术原理与实践》主题内容。 分享嘉宾 叶正盛&#xff0c;NineData CEO …

多线程同步计数器CountDownLatch,CyclicBarrier,Semaphore

系列文章目录 文章目录 系列文章目录前言前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 CountDownLatch CountDownLatch是一个同步工具类,它允许一个或多个线程等…

【学习】软件验收测试,能否选择第三方检测机构进行测试?

随着信息技术的快速发展&#xff0c;软件已经成为各行各业中不可或缺的一部分。为了保证软件的质量和稳定性&#xff0c;验收测试成为了软件开发过程中至关重要的一环。那么&#xff0c;第三方软件测试机构可以做验收测试吗&#xff1f;我们一起来看下今日的分享。 一、验收测…

MySQL操作DML

目录 1.概述 2.插入 3.更新 4.删除 5.查询 6.小结 1.概述 数据库DML是数据库操作语言&#xff08;Data Manipulation Language&#xff09;的简称&#xff0c;主要用于对数据库中的数据进行增加、修改、删除等操作。它是SQL语言的一部分&#xff0c;用于实现对数据库中数…

diffusion model(十五) : IP-Adapter技术小结

infopaperhttps://arxiv.org/pdf/2308.06721.pdfcodehttps://github.com/tencent-ailab/IP-Adapterorg.Tencent AI Lab个人博客地址http://myhz0606.com/article/ip_adapter 1 Motivation 为了对文生图diffusion model进行特定概念的定制&#xff0c;常用LoRA[1]、textual in…

Android Studio 生成 keystore 签名文件及打包验证流程

一、创建keystore签名文件 1、在菜单栏中&#xff0c;依次点击 Build - Generate Signed Bundle/Apk...(生成签名) 2、选择 APK 选项&#xff0c;点击按钮 Next 到下一步 3、新建key store秘钥文件&#xff0c;点击按钮 Next 到下一步 4、按如下提示填写信息&#xff0c;点击按…

JAVA POI Excel 使用数组公式 FREQUENCY

平台及依赖 JAVA 17POI版本 <dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>5.2.5</version></dependency><dependency><groupId>org.apache.poi</groupId><art…

【RISC-V 指令集】RISC-V 向量V扩展指令集介绍(四)- 配置和设置指令(vsetvli/vsetivli/vsetvl)

1. 引言 以下是《riscv-v-spec-1.0.pdf》文档的关键内容&#xff1a; 这是一份关于向量扩展的详细技术文档&#xff0c;内容覆盖了向量指令集的多个关键方面&#xff0c;如向量寄存器状态映射、向量指令格式、向量加载和存储操作、向量内存对齐约束、向量内存一致性模型、向量…

蓝桥杯模拟赛练习题—— 燃烧你的卡路里

目标 请在 js/index.js 和 index.html 文件中补全代码&#xff0c;完成以下目标&#xff1a; 点击“定制方案”按钮后&#xff0c;弹出侧滑页面&#xff0c;所使用的组件为 el-drawer&#xff0c;相关属性如下&#xff1a; 参数说明类型默认值v-model是否显示 Drawerboolean…

短视频技术课程在哪学?来这几个资源网站看看,是你需要的

做短视频&#xff0c;有时候就像是做饭&#xff0c;素材好比是食材&#xff0c;没了好食材&#xff0c;怎么做都是不是味儿。今天&#xff0c;我得跟大家好好聊聊&#xff0c;作为一个剪辑界的“老油条”&#xff0c;我是怎样在这个素材的海洋里捞到宝贝的。九才素材网&#xf…

新手养猫必备!福派斯三文鱼益生菌猫粮,让猫咪更健康

亲爱的朋友们&#xff0c;我知道你们中的许多人可能正在考虑养猫&#xff0c;或者刚刚成为了一位猫奴。对于新手来说&#xff0c;选择合适的猫粮可能是一个令人困惑的问题。今天&#xff0c;我想向大家推荐一款非常适合新人的猫粮——福派斯三文鱼益生菌猫粮。 &#x1f43e; 首…

船气废弃锅炉三维仿真vr交互展示降低培训门槛

火化炉是殡葬行业的核心设备&#xff0c;其操作技艺对于专业人才的培养至关重要。然而&#xff0c;传统实践教学受限于时间、场地、设备损耗等多重因素&#xff0c;难以给予学生充分的实操机会。面对这一挑战&#xff0c;我们创新推出了火化炉vr三维仿真培训软件&#xff0c;以…

中颖51芯片学习3. 定时器

中颖51芯片学习3. 定时器 一、SH79F9476定时器简介1. 简介2. 定时器运行模式 二、定时器21. 说明&#xff08;1&#xff09;时钟&#xff08;2&#xff09;工作模式 2. 寄存器&#xff08;1&#xff09;控制寄存器 T2CON&#xff08;2&#xff09;定时器2模式控制寄存器 T2MOD …

[大模型]Baichuan2-7B-chat FastApi 部署调用

Baichuan2 介绍 Baichuan 2 是百川智能推出的新一代开源大语言模型&#xff0c;采用 2.6 万亿 Tokens 的高质量语料训练。在多个权威的中文、英文和多语言的通用、领域 benchmark 上取得同尺寸最佳的效果。 环境准备 在autodl平台中租一个3090等24G显存的显卡机器&#xff0c;…