文章目录

  • 定义
  • 代码实现
    • 一、Github代码地址
    • 二、节点
    • 三、树实现接口
    • 四、4种遍历方式
    • 五、搜索
    • 六、删除
    • 七、插入
  • 结尾

定义

二叉搜索树(Binary Search Tree),又名二叉排序树(Binary Sort Tree),它是一种数据结构,支持多种动态集合操作,如 Search、Insert、Delete、Minimum 和 Maximum 等,二叉查找树相比于其他数据结构的优势在于查找、插入的时间复杂度较低,均为O(log n)。

  1. 若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值;
  2. 若任意节点的右子树不空,则右子树上所有节点的值均大于它的根节点的值;
  3. 任意节点的左、右子树也分别为二叉查找树;

代码实现

一、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种遍历方式

  1. 前序遍历 - 先访问根节点,然后前序遍历左子树,再前序遍历右子树
  2. 中序遍历 - 中序遍历根节点的左子树,然后访问根节点,最后序遍历右子树
  3. 后序遍历 - 先左到右先叶子节点方式遍历左右子树,最后访问根节点
  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)相关推荐

  1. C++二叉搜索树(Binary Search Tree)(附完整源码)

    二叉搜索树Binary Search Tree node结构体定义 Queue结构体定义 二叉搜索树Binary Search Tree算法的完整源码(定义,实现,main函数测试) node结构体定 ...

  2. 二叉搜索树(Binary Search Tree)(Java实现)

    文章目录 1.二叉搜索树 1.1. 基本概念 1.2.树的节点(BinaryNode) 1.3.构造器和成员变量 1.3.公共方法(public method) 1.4.比较函数 1.5.contai ...

  3. go 递归tree关系_Go实现一个二叉搜索树

    什么是二叉搜索树 二叉搜索树(binary search tree,BST[1])也叫排序的二叉树,根节点比左边子树的所有节点都大,比右边子树上的所有节点都小,如下图就是一个二叉搜索树: 要实现一个二 ...

  4. 数据结构与算法(八)二分搜索树(Binary Search Tree)

    本文主要包括以下内容: 二分搜索树的基本概念 二分搜索树的基本操作 1. 插入 2. 删除 3. 查询 实现二分搜索树 二分搜索树的不足 二分搜索树的基本概念 二分搜索树(英语:Binary Sear ...

  5. 【Java 数据结构】实现一个二叉搜索树

    目录 1.认识二叉搜索树 2.实现一个二叉搜索树 2.1 成员变量 2.2 insert 方法 2.3 search 方法 2.4 remove 方法(重点) 3.二叉搜索树总结 1.认识二叉搜索树 ...

  6. 阿里开发者招聘节 | 面试题02-04:给定一个二叉搜索树(BST),找到树中第K小的节点

    为帮助开发者们提升面试技能.有机会入职阿里,云栖社区特别制作了这个专辑--阿里巴巴资深技术专家们结合多年的工作.面试经验总结提炼而成的面试真题这一次将陆续放出(面试题官方参考答案将在专辑结束后统一汇总 ...

  7. 平衡搜索树(Binary Search Tree BST)、索引二叉搜索树

    文章目录 二叉搜索树 索引二叉搜索树 测试代码 这里只给出代码实现. 更多的性质日后再补. 二叉搜索树 // // Created by SongyangJi on 2020/12/23. //#if ...

  8. 数据结构之二叉搜索树(BST)

    数据结构之二叉搜索树(BST) 1. 二叉搜索树定义 二叉搜索树(Binary Search Tree),又名二叉排序树(Binary Sort Tree). 二叉搜索树是具有有以下性质的二叉树: ( ...

  9. b+树时间复杂度_深入理解数据库系统之存储存引擎(二叉搜索树)

    B树是数据库存储引擎使用的最多的存储结构之一.许多开源数据库系统也都大量使B用树作为存储结构,多年来已经证明它们能够胜任大多数使用场景. 早在1971年鲁道夫·拜尔(Rudolph Bayer)和爱德 ...

最新文章

  1. python数学公式代码导入_在Matplotlib图中插入LaTex公式实例
  2. RIPv1 与 RIPv2 基础配置
  3. Linux 虚拟机安装后的配置和一些命令符笔记
  4. 翻译职称计算机能力,2018年职称计算机word2003考点辅导:用好Office2003中的翻译功能...
  5. Egret note
  6. 学习笔记02:直播串讲02
  7. HDU 5608 function (杜教筛)
  8. HDU 4635(强连通分量分解
  9. 2021-2025年中国制革机械行业市场供需与战略研究报告
  10. MongoDB compass 连接不上远程服务器的解决方法
  11. 【必备知识】线激光扫描三维成像原理
  12. vue打包报错error in ./node_modules/view-design/dist/styles/fonts/ionicons.svg?v=3.0.0
  13. [BZOJ2827]千山鸟飞绝
  14. 蓝牙通知栏图标不显示的问题解决
  15. 翻译官方Vellum教程:Breaking and tearing(破裂撕开)
  16. 淘宝/天猫采集商家信息插件
  17. 基于移动位置服务器,基于移动位置的服务系统及方法
  18. 用计算机升级ipad系统软件,ipad2版本太低,设置里又没办法升级,咋自己升级ios系统...
  19. 服务器系统升级文件转移,多可系统迁移说明
  20. Eureka注册中心上服务老是自动挂掉相关问题总结

热门文章

  1. 让淘宝败诉,令携程吃瘪!这群把你气到炸的人,是巨头们最恐惧的天敌
  2. WAIC | 阿里副总裁司罗:大规模语言模型如何赋能行业、创造价值
  3. VS2019清理C++工程的bat文件
  4. 如何做好自己的时间管理
  5. 抖音拿分享链接出来方案
  6. linux mutt接收邮件,Linux下安装使用Mutt邮件客户端并配置邮件警报功能
  7. html文件损坏怎么恢复,SD卡文件损坏怎么办?数据恢复教程来了
  8. IT职场防搞术之初级码农
  9. 《现代操作系统》笔记-内存管理3
  10. data填补 envi no_ENVI实验步骤