数据结构查找-B-树(C语言代码)

#include<stdio.h>
#include<stdlib.h>typedef struct Node
{int level;//树的阶数int keyNum;//关键字的数量int childNum;//孩子数量int* keys;//关键字数组struct Node** children;//孩子数组struct Node* parent;//父亲指针
}Node;//初始化
Node* initNode(int level)
{Node* node = (Node*)malloc(sizeof(Node));//空的根节点申请空间node->level = level;node->keyNum = 0;node->childNum = 0;node->keys = (int*)malloc(sizeof(int) * (level + 1));//0号单元不使用,然后1-level单元是关键字存放,level+1单元是用来分裂的时候node->children = (Node**)malloc(sizeof(Node*) * level);node->parent = NULL;int i;for (i = 0; i < level; i++){//关键字数组和孩子数组申请空间后需要初始化node->keys[i] = 0;node->children[i] = NULL;}//node->keys[i] = 0;//申请空间是level+1的,所以i位置单元需要初始化return node;
}//在结点中寻找合适的插入索引
int findSuiteIndex(Node* node, int data)
{int index;//为什么从1开始,关键字数组keys是从1开始,0号单元不使用,在keys关键组数组找到合适的左右范围内进行插入关键字for (index = 1; index <= node->keyNum; index++){if (data < node->keys[index]){break;//找到这里区间了,就退出,然后就在不大于这个区间进行插入操作 OK?}}return index;//返回这个下标索引(此时index的索引对应的keys[index]值是大于data的,所以你插入需要插入keys[index]的左边,故遇到index-1的时候需要理解过来,因为返回的是index,但是你的位置需要放在index-1)
}//找到合适的叶子结点
Node* findSuiteLeafNode(Node* T, int data)
{if (T->childNum == 0){return T;//孩子数量为0。证明此时就是叶子节点,那就直接返回T}else {//寻找索引 需-1int index = findSuiteIndex(T, data);//返回的肯定是左边的 所以index需要-1//不懂的回去看findSuiteIndex函数的最后一条注释return findSuiteLeafNode(T->children[index - 1], data);}
}void addData(Node* node, int data,Node** T)//Node** T插入函数有可能会改变根结点,所以先引入
{int index = findSuiteIndex(node, data);//mid//找到合适的关键字索引,腾出位置给它,(level+1)就体现了for (int i = node->keyNum; i >= index; i--){node->keys[i + 1] = node->keys[i];}node->keys[index] = data;node->keyNum = node->keyNum + 1;//判断是否进行分裂if (node->keyNum == node->level)//当前关键字数量max == m阶树,那就需要分裂{//找到分裂的位置int mid = node->level / 2 + node->level % 2;//分裂过程Node* lchild = initNode(node->level);Node* rchild = initNode(node->level);//两个新申请的空间 要将mid左右的关键字赋回给他们这两个新申请的空间(int i = 1 关键字是从1开始//左for (int i = 1; i < mid; i++){//lchild->keys[i] = node->keys[i];//左边的空间拿回mid前半部分数据//lchild->keyNum++;addData(lchild, node->keys[i], T);//看不懂的就用前两个注释的代码}//右for (int i = mid + 1; i <= node->keyNum; i++){//rchild->keys[i] = node->keys[i];//rchild->keyNum++;addData(rchild, node->keys[i], T);//看不懂的就用前两个注释的代码}//左右新申请的空间拿回各自的关键字之后,也要拿回连着的孩子//左for (int i = 0; i < mid; i++)//i = 0孩子是从0开始{lchild->children[i] = node->children[i];//给孩子//如果说分裂出去的关键字连有孩子,那么就给左关键字管if (node->children[i] != NULL){node->children[i]->parent = lchild;lchild->childNum++;}}//右int index = 0;for (int i = mid; i < node->childNum; i++){rchild->children[index++] = node->children[i];if (node->children[i] != NULL){node->children[i]->parent = rchild;rchild->childNum++;}}//对父亲进行判断if (node->parent == NULL){//如果此时插入的关键字并没有根节点Node* newParent = initNode(node->level);addData(newParent, node->keys[mid], T);newParent->children[0] = lchild;newParent->children[1] = rchild;newParent->childNum = 2;lchild->parent = newParent;rchild->parent = newParent;*T = newParent;}else//若{//找到mid应处于 node->parent 的哪个区间里int index = findSuiteIndex(node->parent, node->keys[mid]);//上一层//mid是分裂出去上一层,所以lchild 和rchild的parent都是要指向mid的 求index是为了得到mid在这一层(分裂上去之后的这一层)的区间位置lchild->parent = node->parent;rchild->parent = node->parent;//mid的左孩子就是nodenode->parent->children[index - 1] = lchild;//判断mid的右孩子是否有值if (node->parent->children[index] != NULL){//node->parent->childNum - 1实际上就是mid的孩子数量 childNum - 1取得最后(右)的孩子下标,孩子是从0开始的,关键字才是1开始for (int i = node->parent->childNum - 1; i >= index; i--){node->parent->children[i + 1] = node->parent->children[i];//index这个下标索引就空出一个,供rchild插入}}node->parent->children[index] = rchild;//左孩子是本身就连着的,rchild呢才是新增的孩子,故+1就好了childNumnode->parent->childNum++;addData(node->parent, node->keys[mid], T);}}
}
void insert(Node** T, int data)
{Node* node = findSuiteLeafNode(*T, data);addData(node, data, T);	
}
void printTree(Node* T)
{if (T != NULL){for (int i = 1; i <= T->keyNum; i++){printf("%d ", T->keys[i]);}printf("\n");for (int i = 0; i < T->childNum; i++){printTree(T->children[i]);}}}
//查找
Node* find(Node* node, int data)
{if (node == NULL){return NULL;}for (int i = 1; i <= node->keyNum; i++){if (data == node->keys[i]){return node;}else if (data < node->keys[i]){return find(node->children[i - 1], data);}else{if (node->keyNum != i && data < node->keys[i + 1]){return find(node->children[i], data);}}}return find(node->children[node->keyNum], data);
}
int main()
{Node* T = initNode(5);insert(&T, 1);insert(&T, 2);insert(&T, 6);insert(&T, 7);insert(&T, 11);insert(&T, 4);insert(&T, 8);insert(&T, 13);insert(&T, 10);insert(&T, 5);insert(&T, 17);insert(&T, 9);insert(&T, 16);insert(&T, 20);insert(&T, 3);insert(&T, 12);insert(&T, 14);insert(&T, 18);insert(&T, 19);insert(&T, 15);printf("遍历的情况如下:\n");printTree(T);printf("查找如下:\n");Node* node = find(T, 7);if (node){for (int i = 1; i <= node->keyNum; i++) {printf("%d ", node->keys[i]);}}return 0;
}

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

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

相关文章

网页web无插件播放器EasyPlayer.js播放器返回错误 Incorrect response MIME type 的解决方式

在使用EasyPlayer.js播放器进行视频流播放时&#xff0c;尤其是在SpringBoot环境中部署静态资源时&#xff0c;可能会遇到“Incorrect response MIME type”的错误&#xff0c;这通常与WebAssembly&#xff08;WASM&#xff09;文件的MIME类型配置有关。 WASM是一种新的代码格式…

[阻塞队列]

目录 1. 阻塞队列 2. 阻塞队列的优点 (1) 实现服务器之间的"低耦合". (2) 实现"削峰填谷"的功能. 3. 阻塞队列代码举例 4. 自己实现阻塞队列 1. 阻塞队列 我们知道, 标准库中原有的队列Queue及其子类, 都是线程不安全的, 所以java封装了一个名为&quo…

DCA-X 采样示波器

DCA-X 采样示波器 苏州新利通 | 综述 | DCA-X 宽带采样示波器属于我们的数字通信分析仪&#xff08;DCA&#xff09;系列。 这些示波器都是模块化平台&#xff0c;可对 50 Mb/s 到 224 Gb/s 的高速数字设计执行精准的测量。 您可以选择各种插入式模块来配置 DCA-X 主机&…

将webserver部署到公网(使用阿里云服务器)

阿里云轻量应用服务器介绍 这里我是用的是阿里云进行部署&#xff0c;阿里云推出的相关产品包括 云服务器 ECS 和轻量应用服务器。阿里云的指引和说明我觉得还是比较清楚详细的&#xff0c;适合新手。 先来介绍相关的一些名词&#xff1a; 云服务器 ECS&#xff08;Elastic …

【JavaEE进阶】Spring 事务和事务传播机制

目录 1.事务回顾 1.1 什么是事务 1.2 为什么需要事务 1.3 事务的操作 2. Spring 中事务的实现 2.1 Spring 编程式事务(了解) 2.2 Spring声明式事务 Transactional 对比事务提交和回滚的日志 3. Transactional详解 3.1 rollbackFor 3.2 Transactional 注解什么时候会…

Python 实现阿里滑块全攻略

阿里划块技术为开发者提供了高精度的视觉分割能力&#xff0c;而 Python 作为一种简洁高效的编程语言&#xff0c;可以轻松调用阿里划块接口&#xff0c;实现各种场景下的图像分割需求。 Python 调用阿里云分割抠图 - 商品分割接口的步骤如下&#xff1a;首先&#xff0c;开通…

[ComfyUI]Flux:繁荣生态魔盒已开启,6款LORA已来,更有MJ6写实动漫风景艺术迪士尼全套

今天&#xff0c;我们将向您介绍一款非常实用的工具——[ComfyUI]Flux。这是一款基于Stable Diffusion的AI绘画工具&#xff0c;旨在为您提供一键式生成图像的便捷体验。无论您是AI绘画的新手还是专业人士&#xff0c;这个工具都能为您带来极大的便利。 在这个教程中&#xff…

阿里云CDN稳定吗?

在互联网服务中&#xff0c;CDN&#xff08;内容分发网络&#xff09;扮演着至关重要的角色&#xff0c;它能够加速网站加载速度&#xff0c;提升用户体验。那么&#xff0c;作为市场上的领先者之一&#xff0c;阿里云的CDN到底稳定吗&#xff1f;九河云来和你说一说吧。 一、…

Matlab实现鹈鹕优化算法(POA)求解路径规划问题

目录 1.内容介绍 2.部分代码 3.实验结果 4.内容获取 1内容介绍 鹈鹕优化算法&#xff08;POA&#xff09;是一种受自然界鹈鹕捕食行为启发的优化算法。该算法通过模拟鹈鹕群体在寻找食物时的协作行为&#xff0c;如群飞、潜水和捕鱼等&#xff0c;来探索问题的最优解。POA因其…

C++builder中的人工智能(22):在C+++中读取WAV格式的音频文件

在这篇文章中&#xff0c;我们将探讨如何在C中读取WAV格式的音频文件。音频文件是计算机科学和编程中的一个重要组成部分&#xff0c;正确使用音频可以为娱乐应用程序增添乐趣&#xff0c;或者在业务应用程序中提醒用户重要事件或状态变化。在这篇文章中&#xff0c;我们将解释…

.NET Core 应用程序如何在 Linux 中创建 Systemd 服务 ?

.NET Core 和 Linux 已经成为一个强大的组合&#xff0c;为开发人员提供了一个灵活、高性能的平台来构建和运行应用程序。在 Linux 上部署 .NET Core 应用程序的一个关键方面是利用 systemd 服务来确保应用程序顺利运行&#xff0c;在开机时自动启动&#xff0c;并在失败后重新…

@RestController 源码解读:解决 Web 开发中 REST 服务的疑难杂症

目录 一、RestContrller注解 1.1 查看底层源码 1.2 AliasFor注解说明 1.2.1 注解别名 1.2.2 元数据别名 1.3 value() 方法的作用 一、RestContrller注解 1.1 查看底层源码 首先编写如下内容&#xff1a; RestController public class TestController {} 按住 Ctrl &am…

vs2019托管调试助手 “ContextSwitchDeadlock“错误

错误描述 托管调试助手 "ContextSwitchDeadlock":“CLR 无法从 COM 上下文 0xd183e0 转换为 COM 上下文 0xd18328&#xff0c;这种状态已持续 60 秒。拥有目标上下文/单元的线程很有可能执行的是非泵式等待或者在不发送 Windows 消息的情况下处理一个运行时间非常长…

H.264/H.265播放器EasyPlayer.js RTSP播放器关于webcodecs硬解码H265的问题

EasyPlayer.js H5播放器&#xff0c;是一款能够同时支持HTTP、HTTP-FLV、HLS&#xff08;m3u8&#xff09;、WS视频直播与视频点播等多种协议&#xff0c;支持H.264、H.265、AAC、G711A、Mp3等多种音视频编码格式&#xff0c;支持MSE、WASM、WebCodec等多种解码方式&#xff0c…

免费在线图片翻译工具:PicTech

文章目录 简介编辑功能 简介 PicTech是一款免费的在线图片翻译工具。图片翻译&#xff0c;顾名思义就是把图片中的文字翻译成另外一种语言&#xff0c;并以图片的形式输出。这种功能在手机的词典软件中似乎还挺常见的&#xff0c;但作为一种在线工具我还是第一次见。 其使用过…

【Vue】Vue3.0(二十)Vue 3.0 中mitt的使用示例

上篇文章 【Vue】Vue3.0&#xff08;十九&#xff09;Vue 3.0 中一种组件间通信方式-自定义事件 &#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;Vue专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年11月11日12点23分 文章目录 一、mitt 在…

搭建监控系统Prometheus + Grafana

公司有个技术分享会&#xff0c;但是业务忙&#xff0c;没时间精心准备&#xff0c;所以就匆匆忙忙准备分享一下搭建&#xff08;捂脸哭&#xff09;。技术含量确实不多&#xff0c;但是分享的知识确实没问题。 以下是搭建过程&#xff1a; 一、讲解 Prometheus Prometheus 最…

蓝桥杯真题——班级活动

目录 题目链接&#xff1a;1.班级活动 - 蓝桥云课 题目描述 输入格式 输出格式 样例输入 样例输出 样例说明 评测用例规模与约定 解法一&#xff1a;Map集合处理 举个例子 Java写法&#xff1a; C写法&#xff1a; 运行时间 时间复杂度和空间复杂度 时间复杂度…

Win10下使用Anaconda安装GPU版本PyTorch

一、判断是否有Nvidia(英伟达)显卡 右键开始菜单&#xff0c;在弹出选项中选择任务管理器。 点性能选项&#xff0c;然后点GPU。在右上方会显示GPU名称&#xff0c;只有带NVIDIA的英伟达显卡的电脑才能安装GPU版本&#xff0c;否则其他的就只能安装CPU版本。 二、安装CUDA 首…

精品案例PPT | 企业架构及典型设计方案

本文全面介绍企业架构的理论和实践&#xff0c;包括企业架构的概述、元模型、视图、业务架构、应用架构、数据架构、技术架构以及企业架构管控等内容&#xff0c;有助于企业管理者理解和设计企业级的IT架构&#xff0c;确保架构的全局性、整体性、关联性、可控制性、可实现性和…