二叉搜索树--二叉排序树

特性

  • 搜索依据的关键码,所有节点的关键码互不相同
  • 非空左子树的所有键值小于其根结点的键值。
  • 非空右子树的所有键值大于其根结点的键值。
  • 左、右子树都是二叉搜索树。
  • 左 <  根  < 右,左右都是二叉排序树
  • 二叉搜索树-中序遍历从小到大有序

创建二叉搜索树

插入节点:

先判断是否是空树,

判断插入的节点是否存在,存在就不插入,

根据二叉搜索树的性质进行判断是插入左边还是右边

遍历二叉搜索树

编写四个函数,Pre,Next,First,Last。分别表示前驱节点,下一个节点,第一个节点和最后一个节点。

Pre函数,找前驱节点,如果有左子树,则前驱节点是该子树的最后一个节点last,如果没有左子树,判断该节点对于它的父节点来说是否是右孩子(用于判断父节点是否遍历)。

删除节点

删除叶子,删除单分支,删除双分支,删除单分支的根

删除双分支的时候先找到他的直接后继,将直接后继的数据值放到要删的节点位置,将要删的节点删除。

删除单分支的时候,判断时该节点的左孩子还是右孩子,删除该节点后挂到相应的位置。

结构设计

typedef int KeyType;
typedef struct BstNode{struct BstNode* leftchild;struct BstNode* rightchild;struct BstNode* parent;KeyType data;
}BSTNode;typedef struct{BstNode* root;int cursize;
}BSTree;

void InitTree(BSTree * ptree){assert(ptree != nullptr);ptree ->cursize = 0;ptree->root  = nullptr;
}
BstNode*  FindVal(BSTree* bsptr, KeyType k){BstNode * ptr = bsptr->root;while(ptr  && ptr->data != k){ptr = k < ptr->data ? ptr->leftchild : ptr->rightchild;}return ptr;
}
BstNode* Search(BstNode* bsptr, KeyType k){if(bsptr == nullptr || bsptr->data == k)    return bsptr;else if(bsptr->data < k)    return Search(bsptr->rightchild,  k);else return Search(bsptr,  k);
}
BstNode *Search_val(BSTree* bsptr, KeyType k){return Search(bsptr->root, k);
}
BstNode * BuyNode(){BstNode* s = (BstNode *) calloc(1, sizeof(BstNode));if(nullptr == s)   exit(EXIT_FAILURE);return s;
}
void FreeNode(BstNode * ptr){free(ptr);
}bool Insert_Item(BSTree* ptree, const KeyType kx){assert(ptree != nullptr);if(ptree -> root == nullptr){ptree -> root = BuyNode();ptree->cursize = 1;ptree ->root->data = kx;return true;}BstNode * ptr = ptree ->root, *pa = nullptr;while(ptr != nullptr || ptr ->data != kx){pa = ptr;ptr = ptr->data > kx ? ptr->leftchild : ptr->rightchild;}if( ptr != nullptr && ptr->data == kx){return false;}ptr = BuyNode();ptr->data = kx;ptr->parent = pa;if(ptr->data > pa->data){pa->rightchild = ptr;}else{pa->leftchild = ptr;}ptree->cursize += 1;return true;}
void InOrder(BstNode * ptr){while(ptr){InOrder(ptr->leftchild);cout << ptr->data << " ";InOrder(ptr->rightchild);}
}void InOrder(BSTree * ptree){assert(ptree != nullptr);InOrder(ptree->root);cout <<endl;}BstNode* First(BstNode * ptr){while(ptr != nullptr && ptr->leftchild !=nullptr){ptr = ptr->leftchild;}return ptr;
}
BstNode * Last(BstNode * ptr){assert(ptr != nullptr) ;while(ptr != nullptr && ptr->rightchild != nullptr){ptr =ptr->rightchild;}return ptr;
}BstNode * Next(BstNode * ptr){if(nullptr == ptr)  return nullptr;if(ptr->rightchild != nullptr){return First(ptr->rightchild);}else{BstNode * pa = ptr->parent;while(pa!= nullptr && pa->leftchild != ptr){ptr= pa;pa = ptr->parent;}return pa;}
}BstNode* Pre(BstNode * ptr){if(nullptr == ptr)  return ptr;if(ptr->leftchild != nullptr){return Last(ptr->leftchild);}else{BstNode * pa = ptr->parent;while(pa != nullptr && pa ->rightchild  != ptr){ptr = pa;pa = ptr->parent;}return pa;}
}
void ResNIcieOrder(BSTree * ptree){assert(ptree != nullptr);for(BstNode * ptr = Last(ptree->root); ptr != nullptr; ptr =Pre(ptr)){cout << ptr->data <<" ";}cout << endl;
}
void NiceInOrder(BSTree * ptree){assert(ptree != nullptr);for(BstNode * ptr = First(ptree->root); ptr != nullptr; ptr = Next(ptr)){cout << ptr->data <<" ";}cout << endl;
}
bool Remove(BSTree * ptree, const KeyType kx){assert(ptree != nullptr);if(ptree->root == nullptr)    return false;BstNode * ptr = FindVal(ptree, kx);if(ptr == nullptr)  return false;//2leafif(ptr ->leftchild != nullptr && ptr ->rightchild != nullptr){BstNode * nextnode = Next(ptr);ptr->data= nextnode->data;ptr = nextnode;} ///oneleafBstNode * child = ptr->leftchild != nullptr ? ptr->leftchild : ptr ->rightchild;BstNode * pa = ptr->parent;if(child != nullptr)    child->parent = pa;if(pa != nullptr){if(pa->leftchild == ptr){pa->leftchild =child;}else{pa->rightchild = child;}}else{ptree->root = child;}FreeNode(ptr);ptree->cursize -= 1;return true;
}
int main(){BSTree bstree = {0};KeyType ar[] = {53, 17,78,9,45,65,87,23,81,94,88};int n = sizeof(ar) / sizeof(ar[0]);InitTree(&bstree);for(int i = 0; i < n ; ++i){Insert_Item(&bstree, ar[i]);}InOrder(&bstree);//NiceInOrder(&bstree);//ResNIcieOrder(&bstree);KeyType kx;return 0;
}

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

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

相关文章

精通Spring整合MyBatis:架构师的实践指南

引言&#xff1a; 介绍Spring和MyBatis的基本概念及其在Java应用开发中的重要性。 整合原理 在整合Spring和MyBatis时&#xff0c;关键在于理解两者是如何协同工作的。Spring框架主要负责管理Java应用的生命周期和依赖注入&#xff0c;而MyBatis则专注于数据库操作和映射。 …

c++知识总结

一 细碎知识 1.9 I 1.9.1 inline 参考 C语言中头文件中的 static inline 函数以及 __attribute__((always_inline)) 强制内联展开-CSDN博客https://blog.csdn.net/m0_37616597/article/details/104138980 慎用 inline 内联能提高函数的执行效率,为什么不把所有的函数都定…

高分辨率台阶仪,精准掌控细节测量

什么是台阶仪&#xff1f; 台阶仪是一款超精密接触式微观轮廓测量仪&#xff0c;可以对微米和纳米结构进行膜厚和薄膜高度、表面形貌、表面波纹和表面粗糙度等的测量。 什么是台阶仪分辨率&#xff1f; 台阶仪分辨率是指在台阶仪的测量范围内&#xff0c;仪器能够精确分辨出的…

等保2.0的变化

1法律地位得到确认 《中华人民共和国网络安全法》第21条规定“国家实行网络安全等级保护制度”&#xff0c;要求“网络运营者应当按照网络安全等级保护制度要求&#xff0c;履行安全保护义务”&#xff1b;第31条规定“对于国家关键信息基础设施&#xff0c;在网络安全等级保护…

外包干了2年,技术退步明显...

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试」资…

5.2 Linux FTP 服务

1、概念介绍 FTP&#xff08;File Transfer Protocol:文件传输协议&#xff09;作用Internet 上用来传送文件的协议 FTP Server&#xff08;File Transfer Protocol Server&#xff09;是在互联网/局域网上提供文件存储和访问服务的计算机&#xff0c;它们依照FTP协议提供服务…

Sqoop安装与配置-shell脚本一键安装配置

文章目录 前言一、使用shell脚本一键安装1. 复制脚本2. 增加执行权限3. 执行脚本4. 加载用户环境变量5. 查看是否安装成功 总结 前言 本文介绍了如何使用Shell脚本一键安装Sqoop。Sqoop是一个用于在Apache Hadoop和结构化数据存储&#xff08;如关系数据库&#xff09;之间传输…

优先考虑泛型

Java中的泛型&#xff08;Generics&#xff09;提供了一种参数化类型的机制&#xff0c;使得你可以编写更灵活、类型安全的代码。下面是一个例子&#xff0c;说明在Java中优先考虑泛型的好处&#xff1a; 考虑一个简单的容器类&#xff0c;它可以存储任意类型的元素&#xff0…

【Avue】点击新增再点击表单得radio选项出现新表单,且编辑页面关不掉新表单处理方法

一、问题描述 1、点击新增 2、 点击radio选择值 1、点击否得时候没反应 2、点击是得时候出现新表单 2.1、旧代码 {label: 是否危险源,prop: isBigdanger,searchLabelWidth: 120,overHidden: true,span: 24,rules: [{required: true,message: 请选择是否重大危险源,trigger: bl…

孟德尔随机化+WGCNA+预后模型,7+轻松get

今天给同学们分享一篇生信文章“Exploring the causality and pathogenesis of systemic lupus erythematosus in breast cancer based on Mendelian randomization and transcriptome data analyses”&#xff0c;这篇文章发表在Front Immunol期刊上&#xff0c;影响因子为7.3…

浅显易懂 @JsonIgnore 的作用

1.JsonIgnore作用   在json序列化/反序列化时将java bean中使用了该注解的属性忽略掉 2.这个注解可以用在类/属性上   例如&#xff1a;在返回user对象时&#xff0c;在pwd属性上使用这个注解&#xff0c;返回user对象时会直接去掉pwd这个字段&#xff0c;不管这个属性有没…

【Idea】SpringBoot项目中,jar包引用冲突异常的排查 / SM2算法中使用bcprov-jdk15to18的报错冲突问题

问题描述以及解决方法&#xff1a; 项目中使用了bcprov-jdk15to18 pom依赖&#xff0c;但是发现代码中引入的版本不正确。 追溯代码发现版本引入的是bcprov-jdk15on&#xff0c;而不是bcprov-jdk15to18&#xff0c;但是我找了半天pom依赖也没有发现有引入bcprov-jdk15on依赖。…

MySQL常见死锁的发生场景以及如何解决

死锁的产生是因为满足了四个条件&#xff1a; 互斥占有且等待不可强占用循环等待 这个网站收集了很多死锁场景 接下来介绍几种常见的死锁发生场景。其中&#xff0c;id 为主键&#xff0c;no&#xff08;学号&#xff09;为二级唯一索引&#xff0c;name&#xff08;姓名&am…

Vue.js 使用基础知识

Vue.js 是一款用于构建用户界面的渐进式框架&#xff0c;它专注于视图层。Vue.js 不同于传统的 JavaScript 框架&#xff0c;它采用了组件化的开发方式&#xff0c;使得开发者可以更加高效和灵活地构建交互式的 Web 应用程序。 目录 什么是 Vue.js安装 Vue.jsVue 实例模板语法插…

bat 脚本的常用特殊符号

1、 命令行回显屏蔽符 2、% 批处理变量引导符 3、> 重定向符 4、>> 重定向符 5、<、>&、<& 重定向符 6、| 命令管道符 7、^ 转义字符 8、& 组合命令 9、&& 组合命令 10、|| 组合命令 11、"" 字符串界定符 12、, 逗号…

数据库表1和表2对比出差异列 将表1的插入表2

SQLserver2019表1和表2对比出差异列&#xff0c;将表1的插入表2 写成存储过程&#xff0c;传的参为表名 两个表名一致&#xff0c;表结构可能不一致&#xff0c;可能一致&#xff0c;如何快速对比两个表&#xff0c;将需要的字段自动添加至需要的表中 字段大小是一致的吧 -- …

卷积神经网络(CNN)中感受野的计算问题

感受野 在卷积神经网络中&#xff0c;感受野&#xff08;Receptive Field&#xff09;的定义是卷积神经网络每一层输出的特征图&#xff08;feature map&#xff09;上每个像素点在原始图像上映射的区域大小&#xff0c;这里的原始图像是指网络的输入图像&#xff0c;是经过预处…

c++ 中多线程的相关概念与多线程类的使用

1、多线程相关概念 1.1 并发、并行、串行 并发&#xff08;Concurrent&#xff09;&#xff1a;并发是指两个或多个事件在同一时间间隔内运行。在操作系统中&#xff0c;是指一个时间段中有几个程序都处于已启动运行到运行完毕之间&#xff0c;且这几个程序都是在同一个处理机…

Visual Studio编辑器中C4996 ‘scanf‘: This function or variable may be unsafe.问题解决方案

目录 ​编辑 题目&#xff1a;简单的ab 1. 题目描述 2. 输入格式 3. 输出格式 4. 样例输入 5. 样例输出 6. 解题思路 7. 代码示例 8. 报错解决 方案一 方案二 方案三 方案四 总结 题目&#xff1a;简单的ab 1. 题目描述 输入两个整数a和b&#xff0c;…

ISP去噪(2)_np 噪声模型

#灵感# ISP 中的去噪&#xff0c;都需要依赖一个噪声模型。很多平台上使用采集的raw进行calibration&#xff0c;可以输出这个模型&#xff0c;通常称为 noise profile。 目录 名词解释&#xff1a; 标定方法&#xff1a; 校准出的noise profile: noise profile 作用域&am…