当前位置:网站首页>树——二叉排序树(BST)
树——二叉排序树(BST)
2022-08-03 05:25:00 【JanNinth】
二叉排序树
- 概念
- 查找
- 插入
- 删除(难点)
1、概念
- 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
- 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
- 它的左右子树也分别为二叉搜索树
注:二叉树的中序遍历结果是一个有序数列
2、查找
给定一个数组,把它变为二叉搜索树
先定义二叉树结构:
type LinkNode struct{
Val int
Left *LinkNode
Right *LinkNode
}
注:二叉排序树最好情况为:完全二叉树 O(logn)
最坏情况为:退化为单链表O(n)
二叉树查找:
// 查找
// 类似二分查找的树化
func (root *LinkNode) SearchTree(targer int) *LinkNode {
if root == nil {
return nil
}
for root != nil {
if root.Val > targer {
root = root.Left
} else if root.Val < targer {
root = root.Right
} else {
return root
}
}
return nil
}
3、插入
// 插入数据
// 如果插入的元素已存在,直接返回false
// 需要随时记录父节点的位置
func (root *LinkNode) insertTree(targer int) bool {
node := &LinkNode{Val: targer}
if root == nil {
root.Val = targer
}
var parent *LinkNode
cur := root
for cur != nil {
if cur.Val == targer { // 有重复元素则返回
return false
} else if cur.Val > targer {
parent = cur // 保留当前节点
cur = cur.Left
} else {
parent = cur
cur = cur.Right
}
}
if parent.Val > targer {
parent.Left = node
} else {
parent.Right = node
}
return true
}
4、删除
有两种情况
- 被删除节点:左孩子存在,右孩子为空 或者 右孩子存在左孩子为空
- 被删除节点:左孩子右孩子都不为空
解决:
第一种情况直接让左/右孩子直接代替被删除节点
第二种情况需要进行 旋转 处理!!!
func (root *LinkNode) remove(targer int) bool {
if root == nil { // 树为空,不存在要删除的节点
return false
}
var parent *LinkNode // 被删除节点的父节点
cur := root // 复制一份
for cur != nil {
if cur.Val == targer {
removeKey(parent, cur)
return true
} else if cur.Val > targer {
parent = cur
cur = cur.Left
} else {
parent = cur
cur = cur.Right
}
}
return false
}
// 处理三种情况(其中两种类似)
func (root *LinkNode) removeKey(parent *LinkNode, cur *LinkNode) {
if cur.Left == nil { // 被刪除节点左孩子为空
if cur == root { // 被删除节点为 根节点
root = root.Right
} else if cur == parent.Left { // 被删除节点 在父节点的左边
parent.Left = cur.Right
} else { // 被删除节点 在父节点的右边
parent.Right = cur.Right
}
} else if cur.Right == nil {
if cur == root {
root = root.Left
} else if cur == parent.Left {
parent.Left = cur.Left
} else {
parent.Right = cur.Left
}
} else { // 处理最复杂的情况。被删除节点左右孩子都不为空
// 一般取被删除节点的右孩子的最小值,替换被删除节点
parentNode := cur // 保存被删除的节点
minNode := cur.Right // 获取被删除节点的右节点(被删除节点的右孩子)
for parentNode != nil {
parentNode = minNode
minNode = minNode.Left
}
// 找到合适的节点(右孩子的最小值)
cur.Val = minNode.Val
if parentNode.Left == minNode {
parentNode.Left = minNode.Right
} else {
parentNode.Right = minNode.Right // 用于处理右孩子为单链表结构
}
}
}
验证:中序遍历
// 中序遍历 用于验证是否成功
func (root *LinkNode) midPrint() []int {
var res []int
var dfs func(*LinkNode)
dfs = func(root *LinkNode) {
if root == nil {
return
}
if root.Left != nil {
dfs(root.Left)
}
res = append(res, root.Val)
if root.Right != nil {
dfs(root.Right)
}
}
dfs(root)
return res
}
func main() {
// 构建二叉树
root := &LinkNode{Val: 4}
root2 := &LinkNode{Val: 2}
root3 := &LinkNode{Val: 6}
root4 := &LinkNode{Val: 1}
root5 := &LinkNode{Val: 5}
root6 := &LinkNode{Val: 7}
root.Left = root2
root.Right = root3
root2.Left = root4
root3.Left = root5
root3.Right = root6
fmt.Println(root.SearchTree(8)) // 查找元素 8
res := root.midPrint()
fmt.Println(res) // 打印中序遍历的二叉树
fmt.Println(root.insertTree(10)) // 插入元素10
fmt.Println(root.remove(4)) // 删除元素4(根节点)
res = root.midPrint()
fmt.Println(res) // 打印中序遍历的二叉树
}
结果:
<nil>
[1 2 4 5 6 7]
true // 插入成功
true // 删除成功
[1 2 5 6 7 10]
边栏推荐
- 自监督论文阅读笔记 Ship Detection in Sentinel 2 Multi-Spectral Images with Self-Supervised Learning
- 损失函数(第五周)
- 自监督论文阅读笔记 Self-supervised Learning in Remote Sensing: A Review
- AI智能剪辑,仅需2秒一键提取精彩片段
- 剑指 Offer II 001. 整数除法
- cb板上常用的电子元器件都有哪些?
- 自监督论文阅读笔记 DetCo: Unsupervised Contrastive Learning for Object Detection
- page fault-页异常流程
- ZEMAX | 绘图分辨率结果对光线追迹的影响
- 九、请介绍类加载过程,什么是双亲委派模型?
猜你喜欢
pandoc -crossref插件实现markdwon文档转word后公式编号自定义
softmax和最大熵
window下VS2022封装动态库以及调用动态库
增强光学系统设计 | Zemax 全新 22.2 版本产品现已发布!
基于南航app直减自动出票
ZEMAX | 在OpticStudio中建立扩增实境(VR)头戴式显示器
ZEMAX | 在设计抬头显示器(HUD)时需要使用哪些工具?
MATLAB自带的dwt2和wavedec2函数实现基于小波变换的自适应阈值图像边缘检测
自监督论文阅读笔记 Self-supervised Learning in Remote Sensing: A Review
剑指 Offer II 001. 整数除法
随机推荐
自监督论文阅读笔记 DetCo: Unsupervised Contrastive Learning for Object Detection
MATLAB给多组条形图添加误差棒
ZEMAX | 如何使用渐晕系数
交叉熵(第六周)
SQLMAP介绍及使用
SolidWorks 操作视频 | 隐藏高手必备工具Defeature,让设计隐藏更彻底
ZEMAX | 如何围绕空间中的任何点旋转任何元素
VSCODE 常见问题
自监督论文阅读笔记 Self-supervised Learning in Remote Sensing: A Review
二分查找4 - 搜索旋转排序数组
ZEMAX | 如何创建复杂的非序列物体
最优化方法概述
classpath: comparison with classpath*
常见的电容器有哪些?唯样商城
神经网络基础
MATLAB给多组条形图添加误差棒
嵌入汇编-1 格式讲解
深度学习理论课程第八、九、十章总结
window下VS2022封装动态库以及调用动态库
自监督论文阅读笔记Index Your Position: A Novel Self-Supervised Learning Method for Remote Sensing Images Sema