二叉树排序树插入、创建、删除和查找
二叉树排序树插入、创建、删除和查找
二叉排序树的概念
二叉排序树又称二叉查找树,它或者是一棵空树,或者是具有下列性质的二叉树
- 若它的左子树不为空,则左子树上所有结点的值均小于根结点的值
- 若它的右子树不为空,则右子树上所有结点的值均小于根节点的值
- 它的左右子树也同样是二叉排序树
二叉排序树的插入
二叉排序树的插入就是按照二叉树的定义将新结点放到相应位置
实现代码:
// 二叉排序树插入
void search_createBinarySortTree_insert(TreeNode* r, int value)
{int v = 0;while(1){v = r->value;if(value < v){// 当value小于当前结点的值时if(r->lchild == NULL){// 若当前结点没有左子树,将value赋给当前节点的左子树// 创建一个二叉树结点并添加到当前结点的相应位置addTreeNodeChild(r, createTreeNode(value), 'l');return;}else{// 当当前节点有左子树,去左子树找r = r->lchild;}}else{// 当value大于当前节点的值时if(r->rchild == NULL){// 若当前节点没有右子树,将value赋给当前节点的左子树addTreeNodeChild(r, createTreeNode(value), 'r');return;}else{// 当当前节点有右子树时,去右子树找r = r->rchild;}}}
}
通过数组创建二叉排序树
按顺序遍历数组,对每个元素进行二叉排序树插入操作
实现代码:
// 生成二叉排序树
TreeNode* search_createBinarySortTree(int* arr, int len)
{// 因为一开始是空树,所有先创建一个根节点TreeNode* root = createTreeNode(arr[0]);// 对剩下的元素进行插入for(int i = 1; i < len; i ++){search_createBinarySortTree_insert(root, arr[i]);}return root;
}
二叉排序树的删除
二叉排序树的删除有三种情况,叶子结点、有两棵子树的结点、有一棵子树的结点
叶子结点
直接删除即可
有两棵子树的结点
有几种方法可以实现,如①用左子树的最右结点替代当前结点、②用右子树的最左结点替代当前结点。
有一棵子树的结点
用子树替代当前结点即可
实现代码:
// 二叉排序树删除节点
/*
target:要删除的结点
parent:双亲结点
targetIs:要删除的结点是双亲的左孩子还是右孩子,'r'表示右孩子;'l'表示左孩子。为了看起来方便没用0,1表示但发现写起来还是用0,1舒服
*/
void search_createBinarySortTree_delete(TreeNode* target, TreeNode* parent, char targetIs)
{if(target->lchild == NULL && target->rchild == NULL){// 是叶子结点,直接删除deleteTreeNodeChild(parent, targetIs);}else if(target->lchild && target->rchild){TreeNode* tmp;TreeNode* tmp_past = NULL;// 有两个孩子结点/*用右子树的最左边结点替代当前结点*/tmp = target->rchild;while(tmp->lchild){tmp_past = tmp;tmp = tmp->lchild;}// 将要替换的结点从树中删除deleteTreeNodeChild(tmp_past? tmp_past:target, tmp_past? 'l':'r');// 替换要删除的节点// 替换子树tmp->rchild = target->rchild;tmp->lchild = target->lchild;// 替换双亲addTreeNodeChild(parent, tmp, targetIs);}else{// 当前结点只有一个子树char haveChild;if(target->lchild)haveChild = 'l';elsehaveChild = 'r';// 让子树替代当前节点的位置addTreeNodeChild(parent, deleteTreeNodeChild(target, haveChild), targetIs);}// 将要删除节点的子树置空deleteTreeNodeChild(target, 'r');deleteTreeNodeChild(target, 'l');
}
二叉树查找
查找相关的结点,若找到,删除并将其返回,否则返回空
实现代码:
// 二叉树查找
// 返回删除的节点
TreeNode* search_binarySortTreeSearch(TreeNode* root, int value)
{// 用来存放要删除结点的双亲TreeNode* r_past = root;//RL:用来表示要删除的结点相对于双亲是左子树还是右子树char RL; while(1){// 未找到,返回空if(root == NULL) return NULL;// 找到,退出循环if(root->value == value){break;}else if(value < root->value){r_past = root;root = root->lchild;RL = 'l';}else{r_past = root;root = root->rchild;RL = 'r';}}// 删除相应结点,并返回search_createBinarySortTree_delete(root, r_past, RL);return root;
}
代码测试
测试代码:
/*
测试数据:-1,5,2,7,1,4,6,8,3
因为忘记写根节点处理了,所有加个-1结点
*//*
tree:二叉排序树
value:要查找的树
*/
void print_result(TreeNode* tree, int value)
{tree = search_binarySortTreeSearch(tree, value);if(tree){printf("找到值为 %d 的元素\n", tree->value);}else{printf("没找到值为 %d 的元素\n", value);}// 通过先序遍历和中序遍历确认树结构printf("\n先序遍历:");preOrder(tree, "%d ");printf("\n中序遍历:");inOrder(tree, "%d ");
}
样例结构:
测试样例:
删除叶子结点
删除 8 结点
结果:
有两个子树的结点
删除 5 结点
结果:
有一个子树的结点
删除 4 结点
结果:
无效结点
删除 0 结点
结果:
二叉树排序树插入、创建、删除和查找相关推荐
- C++数据结构||为我院设计一个简单的教师信息管理程序。对我院教师进行管理,包括插入、删除、查找、排序等功能。教师信息包括姓名、性别、出生年月、工作年月、学历、职务、住址、电话等信息。
0.先序条件 在文件夹中新建名称"教师信息.txt"的文本文件存储教师信息 visual studio 2017 1.背景 数据结构课程设计的作业 为我院设计一个简单的教师信息管理 ...
- 单链表的创建,插入,删除以及查找
本文章依据学校的实验作业完成 目录 前言 一.链表是什么? 1.概念 2.链表的分类 二.单链表的创建,插入,删除以及查找 1.单链表的存储结构 2.单链表的创建 3.单链表的插入 4.单链表的删除 ...
- Java数据结构与算法-SingleLinkedList单向链表插入,删除,查找,修改详解及代码
SingleLinkedList单向链表插入,删除,查找,修改详解及代码 单向链表学习目标 1. 链表的介绍 2. 单向链表的存储特点以及原理 3. 基本操作:插入,删除等 4. 单向链表应用场景举例 ...
- 利用开放定址法实现散列表的创建、插入、删除、查找操作_散列表和IO
散列表(也叫哈希表) 直接寻址法 取关键字或关键字的某个线性函数值为散列地址.即H(key)=key或H(key) = a·key + b,其中a和b为常数(这种散列函数叫做自身函数).若其中H(ke ...
- B树、B+树—插入,删除,查询
一.B树 1.插入 在B树中插入关键码key的思路: 对高度为h的m阶B树,新结点一般是插在第h层.通过检索可以确定关键码应插入的结点位置.然后分两种情况讨论: 1. 若该结点中关键码个数小于m-1, ...
- 2 顺序表的插入,删除,查找操作(详细)
一 顺序表的结构体定义和函数声明 #include<iostream> using namespace std; #define ElemType int // 自定义 #define ...
- 二叉查找树的插入,删除,查找
二叉查找树的添加,删除,查找算法: import java.util.Scanner;public class BinarySearchTree<AnyType extends Comparab ...
- 【数据结构】二叉搜索树(BST树)的定义、构建、插入、删除及查找操作
一.概念 二叉搜索树(BST树):又叫二叉排序树,二叉查找树.它或者是一棵空树:或者是具有以下性质的二叉树: 1.每个结点都有一个数据域,且所有节点的数据域互不相同: 2.若它的左子树 ...
- C++ vector的初始化、添加、遍历、插入、删除、查找、排序、释放操作
C++的vector本质上是一个动态数组,数据量不大的情况下,非常方便存储和访问操作,当然,不好的情况是数据量大的情况下,查找效率低,删除操作还会导致大量的数组移动操作. 虽然这样,vector还是一 ...
最新文章
- Html-Css 从入门到放弃(一)基础知识
- NSArray与NSString、NSData,NSDictionary与NSString、NSData 相互转化
- linux进程隐藏 hook readdir函数 挂载覆盖/proc/pid 目录
- unity延迟执行下一行代码_Python代码在Linux环境下执行错误异常
- 将搜索二叉树转换成双向链表
- PHP图像处理:3D图纸、缩放、回转、剪下、水印(三)
- bo蓝牙耳机怎么连接_超简单!电脑连接蓝牙音箱,蓝牙耳机!
- 机器学习笔记(十二):随机梯度下降
- MySQL中的show variables like xxx 详解
- 滚动条插件better-scroll(BScroll)的使用
- Matlab用saveas函数自动编号保存图片
- C语言:实数类型。2021-02-15
- Linux命令总结归纳
- 笔记本电脑的鼠标触控面板问题
- 答群友公式推导疑问:守恒和非守恒公式的动量方程推导
- ppt怎么转pdf?经验分享
- 预防U盘被病毒侵害的方法
- lazarus 中文教程_[最新原创电子书]lazarus开发者入门及中级教程
- 网络流媒体--PS封装格式
- prompt模板模式总结记录
热门文章
- 第三代酷睿i3处理器_10nm+新架构+Iris Plus核显 第十代酷睿到底有多强?
- 【欧拉公式】借助简单的球面几何证明欧拉公式
- 嘀嗒出行一直显示服务器错误,嘀嗒出行注册账号,显示身份信息异常!
- LVS负载均衡面试汇总
- PPT初次制作经验总结
- diskgenius创建efi分区_黑苹果原版安装从零开始之 :MBR转GPT和新建EFI分区详细教程...
- 在word中插入一个电子签名
- 微信公众号JS-SDK开发
- 假设u~N(0, 1), X|u ~ N(u, 1)$,我们一起来推导 u的 posterior(p(u|X))
- js 计算两个日期间隔相差天数