实现一个二叉搜索树(Binary Search Tree)
文章目录
- 定义
- 代码实现
- 一、Github代码地址
- 二、节点
- 三、树实现接口
- 四、4种遍历方式
- 五、搜索
- 六、删除
- 七、插入
- 结尾
定义
二叉搜索树(Binary Search Tree),又名二叉排序树(Binary Sort Tree),它是一种数据结构,支持多种动态集合操作,如 Search、Insert、Delete、Minimum 和 Maximum 等,二叉查找树相比于其他数据结构的优势在于查找、插入的时间复杂度较低,均为O(log n)。
- 若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值;
- 若任意节点的右子树不空,则右子树上所有节点的值均大于它的根节点的值;
- 任意节点的左、右子树也分别为二叉查找树;
代码实现
一、Github代码地址
如果您需要本篇文章的所有代码,我已把所有的代码都传到了Github,希望对您有所帮助
地址:
https://github.com/toArray/dataStruct/tree/main/binarySearchTree
二、节点
定义一下 BST 的结点结构体,结点中除了Data数据域,还包含域 Left, Right 和 Parent,它们分别指向结点的左节点、右节点和父节点。
//Node node
type Node struct {Data int32 //数据域Left *Node //左子树Right *Node //右子树Parent *Node //父节点
}
三、树实现接口
定义了一棵树,主要需要了实现插入节点、删除节点、搜索节点、遍历等几个方法
//BinarySearchTree 二叉搜索树实现接口
type BinarySearchTree interface {Insert(data int32) //插入节点Delete(data int32) //删除节点Search(data int32) *Node //搜索节点GetHeight() int //获得高度RangeLeft(node *Node) //左序遍历(深度优先)RangeMid(node *Node) //中序遍历(深度优先)RangeRight(node *Node) //右序遍历(深度优先)RangeLayer() //层序遍历(广度优先)
}type Tree struct {Root *Node
}
四、4种遍历方式
- 前序遍历 - 先访问根节点,然后前序遍历左子树,再前序遍历右子树
- 中序遍历 - 中序遍历根节点的左子树,然后访问根节点,最后序遍历右子树
- 后序遍历 - 先左到右先叶子节点方式遍历左右子树,最后访问根节点
- 层序遍历 - 从跟节点从上往下逐层遍历,在同一层,按从左到右的顺序对节点逐个访问
/*
RangeLeft
@Desc 左序遍历-中左右
*/
func (t *Tree) RangeLeft(node *Node) {if node != nil {fmt.Printf("%v ", node.Data)t.RangeLeft(node.Left)t.RangeLeft(node.Right)}
}/*
RangeMid
@Desc 中序遍历-左中右
*/
func (t *Tree) RangeMid(node *Node) {if node != nil {t.RangeMid(node.Left)fmt.Printf("%v ", node.Data)t.RangeMid(node.Right)}
}/*
RangeRight
@Desc 右序遍历-左右中
*/
func (t *Tree) RangeRight(node *Node) {if node != nil {t.RangeRight(node.Left)t.RangeRight(node.Right)fmt.Printf("%v ", node.Data)}
}/*
RangeLayer
@Desc 层序遍历
*/
func (t *Tree) RangeLayer() {if t.Root == nil {return}//use queuequeue := []*Node{t.Root}for len(queue) > 0 {node := queue[0]fmt.Printf("%v ", node.Data)if node.Left != nil {queue = append(queue, node.Left)}if node.Right != nil {queue = append(queue, node.Right)}queue = queue[1:]}
}
五、搜索
- 从根结点开始查找,如果树为空,就返回NULL。
- 如果树不空,就让数据X和根结点的数据Data作比较。
- 如果X的值大于根结点的Data,就往右子树中进行搜索;如果X的值小于根结点的Data,就往左子树中进行搜索。
- 如果X的值等于Data,就表示查找完成,返回该结点。
/*
Search
@Desc 搜索
@Param data int32
*/
func (t *Tree) Search(data int32) *Node {if t.Root == nil {return nil}temp := t.Rootfor temp != nil {if temp.Data == data {return temp}if data > temp.Data {temp = temp.Rightcontinue}temp = temp.Left}return nil
}
六、删除
删除总共分3种情况
- 情况一:被删除的节点是叶子节点
- 情况二:被删除的节点只有一个左节点或者右节点
- 情况三:被删除的节点有2个子节点,左节点和右节点
/*
Delete
@Desc 删除节点
*/
func (t *Tree) Delete(data int32) {//空树if t.Root == nil {return}//找到需要删除的节点node := t.Search(data)if node == nil {return}//该节点的父节点parentNode := node.Parent//情况1:属于叶子节点if node.Left == nil && node.Right == nil {//刚好是根节点if parentNode == nil {t.Root = nil} else {if parentNode.Left == node {parentNode.Left = nil //该节点属于父节点的左节点} else {parentNode.Right = nil //该节点属于父节点的右节点}}return}//情况2:该节点只有一个左子节点或者只有一个右子节点if (node.Left != nil && node.Right == nil) || (node.Left == nil && node.Right != nil) {//替代节点replaceNode := node.Leftif node.Right != nil {replaceNode = node.Right}//刚好是父节点if parentNode == nil {replaceNode.Parent = nilt.Root = replaceNode} else {replaceNode.Parent = parentNode //更新替代节点的父节点if parentNode.Left == node {parentNode.Left = replaceNode //该节点属于父节点的左节点} else {parentNode.Right = replaceNode //该节点属于父节点的右节点}}return}//情况3:该节点有2个子节点if node.Left != nil && node.Right != nil {replaceNode := node.rightMinNode() //后继节点//情况3-1//删除的后继节点刚好是右子树if node.Right == replaceNode {if parentNode == nil {replaceNode.Parent = nilt.Root = replaceNode} else {//维护后继节点的左节点和父节点replaceNode.Parent = parentNodeif parentNode.Left == node {parentNode.Left = replaceNode} else {parentNode.Right = replaceNode}}//更新左子树if node.Left != nil {replaceNode.Left = node.Leftnode.Left.Parent = replaceNode}} else {//情况3-2replaceNodeParent := replaceNode.Parent //代替节点的父节点//后继节点没有右子树,维护后继节点的父节点if replaceNode.Right == nil {if replaceNodeParent.Left == replaceNode {replaceNodeParent.Left = nil} else {replaceNodeParent.Right = nil}} else {//后继节点有右子树,维护后继节点的右节点和父节点if replaceNodeParent.Left == replaceNode {replaceNodeParent.Left = replaceNode.Right} else {replaceNodeParent.Right = replaceNode.Right}replaceNode.Right.Parent = replaceNodeParent}//维护替代节点的左右子树,左右子树的父节点变更为替代节点if node.Left != nil {replaceNode.Left = node.Leftnode.Left.Parent = replaceNode}if node.Right != nil {replaceNode.Right = node.Rightnode.Right.Parent = replaceNode}//维护父节点的左右子树replaceNode.Parent = parentNodeif parentNode == nil {t.Root = replaceNode //根节点} else {if parentNode.Left == node {parentNode.Left = replaceNode} else {parentNode.Right = replaceNode}}}}
}
七、插入
/*
Insert
@Desc 插入节点
@Param data int32
*/
func (t *Tree) Insert(data int32) {//tree is nilif t.Root == nil {t.Root = NewNode(data, nil)return}temp := t.Rootvar parent *Nodefor {parent = temp//insert leftif data < temp.Data {if temp.Left != nil {temp = temp.Leftcontinue}temp.Left = NewNode(data, parent)break}//insert rightif temp.Right != nil {temp = temp.Rightcontinue}temp.Right = NewNode(data, parent)break}
}
结尾
备注: 学习中,欢迎指正
参考学习视频: https://www.bilibili.com/video/BV1X5411A73X
效果展示:
实现一个二叉搜索树(Binary Search Tree)相关推荐
- C++二叉搜索树(Binary Search Tree)(附完整源码)
二叉搜索树Binary Search Tree node结构体定义 Queue结构体定义 二叉搜索树Binary Search Tree算法的完整源码(定义,实现,main函数测试) node结构体定 ...
- 二叉搜索树(Binary Search Tree)(Java实现)
文章目录 1.二叉搜索树 1.1. 基本概念 1.2.树的节点(BinaryNode) 1.3.构造器和成员变量 1.3.公共方法(public method) 1.4.比较函数 1.5.contai ...
- go 递归tree关系_Go实现一个二叉搜索树
什么是二叉搜索树 二叉搜索树(binary search tree,BST[1])也叫排序的二叉树,根节点比左边子树的所有节点都大,比右边子树上的所有节点都小,如下图就是一个二叉搜索树: 要实现一个二 ...
- 数据结构与算法(八)二分搜索树(Binary Search Tree)
本文主要包括以下内容: 二分搜索树的基本概念 二分搜索树的基本操作 1. 插入 2. 删除 3. 查询 实现二分搜索树 二分搜索树的不足 二分搜索树的基本概念 二分搜索树(英语:Binary Sear ...
- 【Java 数据结构】实现一个二叉搜索树
目录 1.认识二叉搜索树 2.实现一个二叉搜索树 2.1 成员变量 2.2 insert 方法 2.3 search 方法 2.4 remove 方法(重点) 3.二叉搜索树总结 1.认识二叉搜索树 ...
- 阿里开发者招聘节 | 面试题02-04:给定一个二叉搜索树(BST),找到树中第K小的节点
为帮助开发者们提升面试技能.有机会入职阿里,云栖社区特别制作了这个专辑--阿里巴巴资深技术专家们结合多年的工作.面试经验总结提炼而成的面试真题这一次将陆续放出(面试题官方参考答案将在专辑结束后统一汇总 ...
- 平衡搜索树(Binary Search Tree BST)、索引二叉搜索树
文章目录 二叉搜索树 索引二叉搜索树 测试代码 这里只给出代码实现. 更多的性质日后再补. 二叉搜索树 // // Created by SongyangJi on 2020/12/23. //#if ...
- 数据结构之二叉搜索树(BST)
数据结构之二叉搜索树(BST) 1. 二叉搜索树定义 二叉搜索树(Binary Search Tree),又名二叉排序树(Binary Sort Tree). 二叉搜索树是具有有以下性质的二叉树: ( ...
- b+树时间复杂度_深入理解数据库系统之存储存引擎(二叉搜索树)
B树是数据库存储引擎使用的最多的存储结构之一.许多开源数据库系统也都大量使B用树作为存储结构,多年来已经证明它们能够胜任大多数使用场景. 早在1971年鲁道夫·拜尔(Rudolph Bayer)和爱德 ...
最新文章
- python数学公式代码导入_在Matplotlib图中插入LaTex公式实例
- RIPv1 与 RIPv2 基础配置
- Linux 虚拟机安装后的配置和一些命令符笔记
- 翻译职称计算机能力,2018年职称计算机word2003考点辅导:用好Office2003中的翻译功能...
- Egret note
- 学习笔记02:直播串讲02
- HDU 5608 function (杜教筛)
- HDU 4635(强连通分量分解
- 2021-2025年中国制革机械行业市场供需与战略研究报告
- MongoDB compass 连接不上远程服务器的解决方法
- 【必备知识】线激光扫描三维成像原理
- vue打包报错error in ./node_modules/view-design/dist/styles/fonts/ionicons.svg?v=3.0.0
- [BZOJ2827]千山鸟飞绝
- 蓝牙通知栏图标不显示的问题解决
- 翻译官方Vellum教程:Breaking and tearing(破裂撕开)
- 淘宝/天猫采集商家信息插件
- 基于移动位置服务器,基于移动位置的服务系统及方法
- 用计算机升级ipad系统软件,ipad2版本太低,设置里又没办法升级,咋自己升级ios系统...
- 服务器系统升级文件转移,多可系统迁移说明
- Eureka注册中心上服务老是自动挂掉相关问题总结