数据结构:(代码篇:004)二叉搜索树 BST(二叉查找树)的基本操作

2023-11-10

 

 

 

 

 

1.基本概念

二叉搜索树:是二叉树是真子集,要求:根节点大于或等于左子树的节点值,小于右子树的节点值。

他的中序遍历是有序的。

基本操作有:查找、插入、删除、建树。

查找和插入以及建树都很简单,和二叉树的差不多。删除略微复杂。

2.存储结构

struct node{
	int data;
	node* lchild;
	node* rchild;
};

3.查找

void search(node* root,int v){
	if(root==NULL){
		cout<<"search failed!"<<endl;
		return ;
	}
	if(root->data==v){
		cout<<"search success!"<<root->data<<endl;
	    return ;
	}
	else
	if(root->data>v){
		search(root->lchild,v);
	}
	else
	if(root->data<v){
		search(root->rchild,v);
	}
}

4.插入

新生成节点:

node* newnode(int v){
	node* t1=new node;
	t1->data=v;
	t1->lchild=t1->rchild=NULL;
	return t1;
}
void insert(node* &root,int v){
	if(root==NULL){
		root=newnode(v);
		return ;
	}
	if(root->data>=v){
		insert(root->lchild,v);
	}
	else
	if(root->data<v){
		insert(root->rchild,v);
	}
}

5.建树

node* create(int data[],int len){
	node* root=NULL;
	int i,j;
	for(i=0;i<len;i++)
	{
		insert(root,data[i]);
	}
	return root;
}

6.删除(重头戏!)

删除二叉搜索树中的某一个节点后,要保持其性质不变:左子树<=root<右子树

还需要了解一个节点的前驱和后继:

前驱:

当前节点左子树中最大的节点(但是小于或等于当前节点),也就是左子树中的最右节点

node* findMax(node* root){      // 找到左子树中最大的节点 
	while(root->rchild!=NULL){
		root=root->rchild;
	}
	return root;
} 

后继:

当前节点右子树中最小的节点(但是大于当前节点),也就是右子树中的最左节点

node* findMin(node* root){     // 找到右子树中最小的节点 
	while(root->lchild!=NULL){
		root=root->lchild;
	}
	return root;
}

 

分情况讨论:

  (1) 要删除的节点值在树中不存在(为NULL) ,直接返回。

  (2) 要删除的节点值等于当前访问的节点值

             a. 如果当前访问的节点没有任何子树,则直接把当前节点设为NULL

             b. 如果当前访问过的节点有左子树,则需要找到当前节点的前驱(即左子树里最大的节点值),用前驱的值覆盖

            当前节点的值,然后在左子树里删除其前驱。

             c. 如果当前访问过的节点有右子树,则需要找到当前节点的后继(即右子树里最小的节点值),用后继的值覆盖

            当前节点的值,然后在右子树里删除其后继。

   (3)要删除的节点值小于当前访问的节点值 ,则递归删除其左子树

   (4)要删除的节点值大于当前访问的节点值 ,则递归删除其右子树

void Delete(node* &root,int v){
	if(root==NULL){
		return ;
	}
	if(root->data==v){
		if(root->lchild==NULL&&root->rchild==NULL){
			root=NULL;
		}
		else
		if(root->lchild!=NULL){
			node* pre=findMax(root->lchild);
			root->data=pre->data;
			Delete(root->lchild,pre->data);
		}
		else
		if(root->rchild!=NULL){
			node* next=findMin(root->rchild);
			root->data=next->data;
			Delete(root->rchild,next->data);
		}
	}
	else
	if(root->data>v){
		Delete(root->lchild,v);
	}
	else
	if(root->data<v){
		Delete(root->rchild,v);
	}
}

7.完整的代码

#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
#define range 100
#define NULL 0
struct node{
	int data;
	node* lchild;
	node* rchild;
};
node* newnode(int v){
	node* t1=new node;
	t1->data=v;
	t1->lchild=t1->rchild=NULL;
	return t1;
}
void search(node* root,int v){
	if(root==NULL){
		cout<<"search failed!"<<endl;
		return ;
	}
	if(root->data==v){
		cout<<"search success!"<<root->data<<endl;
	    return ;
	}
	else
	if(root->data>v){
		search(root->lchild,v);
	}
	else
	if(root->data<v){
		search(root->rchild,v);
	}
}
void insert(node* &root,int v){
	if(root==NULL){
		root=newnode(v);
		return ;
	}
	if(root->data>=v){
		insert(root->lchild,v);
	}
	else
	if(root->data<v){
		insert(root->rchild,v);
	}
}
node* create(int data[],int len){
	node* root=NULL;
	int i,j;
	for(i=0;i<len;i++)
	{
		insert(root,data[i]);
	}
	return root;
}
node* findMax(node* root){      // 找到左子树中最大的节点 
	while(root->rchild!=NULL){
		root=root->rchild;
	}
	return root;
} 
node* findMin(node* root){     // 找到右子树中最小的节点 
	while(root->lchild!=NULL){
		root=root->lchild;
	}
	return root;
}
void Delete(node* &root,int v){
	if(root==NULL){
		return ;
	}
	if(root->data==v){
		if(root->lchild==NULL&&root->rchild==NULL){
			root=NULL;
		}
		else
		if(root->lchild!=NULL){
			node* pre=findMax(root->lchild);
			root->data=pre->data;
			Delete(root->lchild,pre->data);
		}
		else
		if(root->rchild!=NULL){
			node* next=findMin(root->rchild);
			root->data=next->data;
			Delete(root->rchild,next->data);
		}
	}
	else
	if(root->data>v){
		Delete(root->lchild,v);
	}
	else
	if(root->data<v){
		Delete(root->rchild,v);
	}
}
void preorder(node* root){
	if(root==NULL){
		return ;
	}
	cout<<root->data<<" ";
	preorder(root->lchild);
	preorder(root->rchild);
}
void inorder(node* root){
	if(root==NULL){
		return ;
	}
	inorder(root->lchild);
	cout<<root->data<<" ";
	inorder(root->rchild);
}
void postorder(node* root){
	if(root==NULL){
		return ;
	}
	postorder(root->lchild);
	postorder(root->rchild);
	cout<<root->data<<" ";
}
void layerorder(node* root){
	queue<node*> s;
	s.push(root);
	node* t=NULL; 
	while(!s.empty()){
		t=s.front();
		s.pop();
		cout<<t->data<<" ";
		if(t->lchild!=NULL)
		s.push(t->lchild);
		if(t->rchild!=NULL)
		s.push(t->rchild);
	}
}
int main(){
	int i,j,k,t,n;
	int data[10];
	node* root=NULL;
	cout<<"请输入节点个数:"<<endl;
	cin>>n;
	cout<<"请输入节点值:";
	for(i=0;i<n;i++)
	cin>>data[i];
	cout<<endl;
	root=create(data,n);
	cout<<"中序遍历:";
	inorder(root);
	cout<<"请输入查找的值:";
	cin>>n;
	search(root,n);
	cout<<"请输入删除的值:";
	cin>>n;
	Delete(root,n); 
	cout<<"中序遍历:";
	inorder(root);
	cout<<endl;
	cout<<"先序遍历:";
	preorder(root);
	cout<<endl;
	cout<<"后序遍历:"; 
	postorder(root);
	cout<<endl;
	cout<<"层序遍历:";
	layerorder(root);
	cout<<endl; 
	return 0;
}

 

代码的力量使我兴奋!

如有错,请指出。新年快乐(*^__^*) 嘻嘻……

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数据结构:(代码篇:004)二叉搜索树 BST(二叉查找树)的基本操作 的相关文章

  • Batch Normalization详解

    Batch Normalization 原理 1 Batch Normalization的提处背景 1 1 常见的帮助收敛的方法 在深度学习中 随着网络层数的加深 模型的收敛难度会越来越大 为了让模型更好的收敛 涌现出了各种各样的调参方法
  • Java8 HashMap源码解析

    HashMap底层数据结构 HashMap底层数据结构是 数组 链 如下图 当满足以下两个条件 链表会转为红黑树 1 数组长度等于或大于64 2 链表长度等于或大于8 如果数组长度小于64 链表长度等于或大于8 不会把链表转为红黑树 而是扩
  • SpringMVC中如何使用注解的方式实现文件上传呢?

    转自 SpringMVC中如何使用注解的方式实现文件上传呢 一 form表单注意事项 上传文件所处的表单 表单必须使用以下属性 enctype multipart form data method POST 二 applicationCon

随机推荐

  • vue-鉴权的两种方法之路由拦截

    vue中鉴权的两种方法 常用的鉴权有两种 一种是路由拦截 一种是动态路由 路由拦截 通过vue router的beforeEach方法进行每一次路由访问的拦截 判断拦截信息中是否有鉴权要求或者权限校验 以此来实现鉴权 如果权限不够 访问的路
  • 透视Matplotlib核心功能和工具包 - Seaborn工具包

    Seaborn是基于Matplotlib构建的功能强大的可视化工具 它使多变量探索性数据分析更加容易和直观 并且增加了一些新类型的图 并且其背景样式和颜色图更加令人愉悦 它具有许多内置的统计功能 使其成为统计数据分析的首选工具 它还具有非常
  • Web学习之TypeScript

    文章目录 一 TypeScript是什么 二 TypeScript配置 三 变量声明 四 解构 五 函数 六 类Class 七 模块Module 八 总结 九 学习资料 一 TypeScript是什么 TypeScript是JavaScri
  • PTA 7-38 等边三角形面积

    PTA 7 38 等边三角形面积 数学基础对于程序设计能力而言很重要 对于等边三角形面积 请选择合适的方法计算之 输入格式 测试数据有多组 处理到文件尾 每组测试输入1个实数表示等边三角形的边长 输出格式 对于每组测试 在一行上输出等边三角
  • Ubuntu 14.04 Tab补全忽略大小写

    0 前言 当目录名以大写字母开头时 通过cd命令进入该目录就不太方便 需要切换到大写输入 如果Tab补全可以忽略大小写的话 这个问题就引刃而解 1 设置方法 1 在 目录中创建 inputrc 2 打开 inputrc 添加如下设置 set
  • 面向产品分析的内容

    声明 本文是学习GB T 42859 2023 航天产品质量问题三个面向分析方法实施要求 而整理的学习笔记 分享出来希望更多人受益 如果存在侵权请及时联系我们 1 范围 本文件规定了航天产品质量问题三个面向分析方法实施的一般要求 程序和分析
  • Pandas库基础知识(一)

    文章目录 1 数据结构 1 Series 数据结构 1 Series对象的创建 2 Series对象的属性 3 Series对象的基本操作 2 DataFrame 数据结构 1 DataFrame对象的创建 2 DataFrame对象的属性
  • scrapy-redis分布式爬虫框架详解

    scrapy redis分布式爬虫框架详解 随着互联网技术的发展与应用的普及 网络作为信息的载体 已经成为社会大众参与社会生活的一种重要信息渠道 由于互联网是开放的 每个人都可以在网络上发表信息 内容涉及各个方面 小到心情日志 大到国家大事
  • sqllab 1-6 练习

    前言 什么是sql注入 攻击者通过构造不同的sql语句来实现对数据库的操作 两个关键 参数用户可控 参数带入数据库查询 基本流程 判断注入点 判断字段数 判断回显点 查询相关内容 判断库名 gt 判断表明 gt 判断列名 gt 判断数据 搭
  • xxl-job详细使用指南

    新建任务说明 本篇文章承接上文 xxl job快速入门指南 上一次和大家简单介绍了下 xxl job 的由来以及使用方法 本篇文章将会详细介绍一些高级使用方法及特性 上文中我们在新建一个任务的时候发现有很多的选项 现在我们来详细聊一聊他们的
  • Jquery加载本地文件出现跨域错误的解决方案

    禁止跨域是浏览器的安全限制机制 会报告上述错误 但是可以通过设置来绕过这个限制 如果经常调试前端代码 可以在本机装个web容器 常见的方式 右击chrome快捷方式 选择 属性 在 快捷方式 下的 目标 中添加 allow file acc
  • HT for Web (Hightopo) 使用心得(6)- 3D场景环境配置(天空球,雾化,辉光,景深)

    在前一篇文章 Hightopo 使用心得 5 动画的实现 中 我们将一个直升机模型放到了3D场景中 同时 还利用动画实现了让该直升机围绕山体巡逻 在这篇文章中 我们将对上一篇的场景进行一些环境上的丰富与美化 让场景更真实一些 具体涉及到的知
  • 微信小程序基础入门的知识点

    微信小程序基础入门的知识点 1 窗口配置 就是在我们app json文件就是对我们微信小程序进行全局配置 它决定我们页面文件的路径 设置多个tab 1 1 pages设置页面的路径 数组的第一个就是我们小程序初始页面 文件名不需要我们写文件
  • C语言入门之自定义结构体数据struct Student { int num; char name[20]; char sex; int age; 类型

    用户自己建立由不同类型数据组成的组合型的数据结构 它称为结构体 例如 一个学生的学号 姓名 性别 年龄 成绩 家庭地址等项 是属于同一个学生的 因此组成一个组合数据 如student 1的变量 反映它们之间的内在联系 struct Stud
  • 字节跳动,华为,阿里巴巴,小米,腾讯 2021大厂面试经历系列之初、中、高级测试工程师面试题汇总(附答案)

    前言 最近看到很多人都在找工作 而且很多人都感觉今年找工作比去年难很多 竞争力也增加不少 因此激发我整理这份资料 希望能帮到正在找或者准备找工作的童鞋们 首先我们能否获得一个面试机会 那肯定是从简历开始 简历需要做好功夫 一份好的简历才足够
  • Springboot集成Jasypt实现配置文件加密

    不容错过的成长之旅 Jasypt介绍 Jasypt是一个java库 它允许开发员以最少的努力为他 她的项目添加基本的加密功能 并且不需要对加密工作原理有深入的了解 用于单向和双向加密的高安全性 基于标准的加密技术 加密密码 文本 数字 二进
  • 解决Windows10中文用户名带来软件无法打开的影响

    众所周知 许多国外的开发软件都不支持中文的文件路径名 即使软件的路径无中文字符 可你系统用户的名称是中文 同样软件无法运行 因为大部分软件的在电脑用户上的缓冲文件都是在 C user 你的用户名称 AppData local temp 解决
  • Power BI和Tableau对比分析,到底要学哪个?

    Power BI和Tableau对比分析 到底要学哪个 一 两个工具优缺点 Power BI Tableau 二 职业需求 前程无忧 智联招聘 三 总结 学习tableau还是power bi想必是很多初学者的疑惑 可以从以下两个角度去考虑
  • 一台服务器想用150个ip,可以吗?

    不可以 一台服务器一次只支持一个ip 可以更换 但每次绑定一个 如果需要多个ip 只能多开服务器 挂店铺的 包括淘宝店铺 拼多多店铺 亚马逊店铺都想店铺不被关联 想买台服务器 可以的 一个店铺买一台服务器 有几个店铺就买几台服务器 ip的带
  • 数据结构:(代码篇:004)二叉搜索树 BST(二叉查找树)的基本操作

    1 基本概念 二叉搜索树 是二叉树是真子集 要求 根节点大于或等于左子树的节点值 小于右子树的节点值 他的中序遍历是有序的 基本操作有 查找 插入 删除 建树 查找和插入以及建树都很简单 和二叉树的差不多 删除略微复杂 2 存储结构 str