Maoyl's blog Maoyl's blog
首页
  • 前端基础

    • HTML
    • CSS
    • CSS动画
    • JavaScript文章
    • stylus
  • 性能优化

    • 《性能优化》笔记
  • 学习笔记

    • 《JavaScript教程》笔记
    • 《JavaScript高级程序设计》笔记
    • 《ES6 教程》笔记
    • 《JavaScript设计模式》笔记
    • 《TypeScript 从零实现 axios》
    • TypeScript笔记
    • JS设计模式总结笔记
  • 前端框架

    • Vue相关
    • React相关
  • 前端监控

    • 前端监控简介
  • 学习笔记

    • 《Vue》笔记
    • 《React》笔记
    • 小程序学习笔记
  • 后端基础

    • Nodejs
  • 学习笔记

    • 数据结构
  • 技术文档
  • GitHub技巧
  • 博客搭建
  • 网页性能
  • 学习笔记

    • 《Git》学习笔记
    • 《Vim》学习笔记
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
  • 网站
  • 资源
  • Vue资源
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

maoyln

日日行,不怕千万里
首页
  • 前端基础

    • HTML
    • CSS
    • CSS动画
    • JavaScript文章
    • stylus
  • 性能优化

    • 《性能优化》笔记
  • 学习笔记

    • 《JavaScript教程》笔记
    • 《JavaScript高级程序设计》笔记
    • 《ES6 教程》笔记
    • 《JavaScript设计模式》笔记
    • 《TypeScript 从零实现 axios》
    • TypeScript笔记
    • JS设计模式总结笔记
  • 前端框架

    • Vue相关
    • React相关
  • 前端监控

    • 前端监控简介
  • 学习笔记

    • 《Vue》笔记
    • 《React》笔记
    • 小程序学习笔记
  • 后端基础

    • Nodejs
  • 学习笔记

    • 数据结构
  • 技术文档
  • GitHub技巧
  • 博客搭建
  • 网页性能
  • 学习笔记

    • 《Git》学习笔记
    • 《Vim》学习笔记
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
  • 网站
  • 资源
  • Vue资源
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 第一讲 基本概念

  • 第二讲 线性结构

  • 第三讲 树(上)

  • 第四讲 树(中)

    • 二叉搜索树
      • 二叉搜索树
        • 名称(别称)
        • 二叉搜索树特征
        • 二叉搜索树操作的特别函数:
        • 找最大和最小元素
      • 二叉搜索树的插入
      • 二叉搜索树的删除
    • 平衡二叉树
  • 第五讲 树(下)

  • 第六讲 图(上)

  • 《数据结构》学习笔记
  • 第四讲 树(中)
maoyln
2024-07-08
目录

二叉搜索树

# 二叉搜索树

静态查账与动态查找 针对动态查找,数据如何组织

# 名称(别称)

二叉搜索树(BST, Binary Search Tree),也称二叉排序树或二叉查找树;

# 二叉搜索树特征

  • 一棵二叉树,可以为空;
  • 如果不为空,满足以下性质::
    1. 非空左子树的所有键值小于其根结点的键值。
    2. 非空右子树的所有键值大于其根结点的键值。
    3. 左、右子树都是二叉搜索树。

错误示例

错误示例

正确示例

正确示例

正确示例

正确示例

# 二叉搜索树操作的特别函数:

  • 💡Position Find( ElementType X, BinTree BST ):从二叉搜索树BST中查找元素X,返回其所在结点的地址;
  • 💡Position FindMin( BinTree BST ):从二叉搜索树BST中查找并返回最小元素所在结点的地址;
  • 💡Position FindMax( BinTree BST ) :从二叉搜索树BST中查找并返回最大元素所在结点的地址。
  • 💡BinTree Insert( ElementType X, BinTree BST )
  • 💡BinTree Delete( ElementType X, BinTree BST )

# 二叉搜索树的查找操作Find

  • 查找从根结点开始,如果树为空,返回NULL
  • 若搜索树非空,则根结点关键字和X进行比较,并进行不同处理:
    • 若X小于根结点键值,只需在左子树中继续搜索;
    • 如果X大于根结点的键值,在右子树中进行继续搜索;
    • 若两者比较结果是相等,搜索完成,返回指向此结点的指针。
// 递归的形式
function findNode(X, BST) {
    if (!BST) return null; // 查找失败

    if (X > BST.data) {
        return findNode(X, BST.right); // 在右子树中继续查找
    } else if (X < BST.data) {
        return findNode(X, BST.left); // 在左子树中继续查找
    } else { // X === BST.data
        return BST; // 查找成功,返回结点的地址
    }
}
1
2
3
4
5
6
7
8
9
10
11
12

由于非递归函数的执行效率高,可将“尾递归”函数改为迭代函数

function findNode(X, BST) {
  while (BST) {
    if (X > BST.data) {
      BST = BST.right; // 向右子树中移动,继续查找
    } else if (X < BST.data) {
      BST = BST.left; // 向左子树中移动,继续查找
    } else { // X === BST.data
      return BST; // 查找成功,返回结点的地址
    }
  }
  return null
}
1
2
3
4
5
6
7
8
9
10
11
12

查找的效率决定于树的高度

# 找最大和最小元素

  • 最大元素一定是在树的最右分枝的端结点上
  • 最小元素一定是在树的最左分枝的端结点上

找最大和最小元素

// 查找最小元素的递归函数
function findMin(BST) {
  if (!BST) {
    return null, // /*空的二叉搜索树,返回null*/
  } else if (!BST.left) {
    return BST; //找到最左叶结点并返回
  } else {
    return findMin(BST.left)
  }
}
1
2
3
4
5
6
7
8
9
10
// 查找最大元素的迭代函数
function findMin(BST) {
  if (BST) {
    while (BST.right) {
      BST = BST.right; // 沿右分支继续查找,直到最右叶结点
    }
  }
  return BST;
}
1
2
3
4
5
6
7
8
9

# 二叉搜索树的插入

〖分析〗关键是要找到元素应该插入的位置,可以采用与Find类似的方法

  • 在下面树上插入35 在下面树上插入35

二叉搜索树的插入算法

function insert(X, BST) {
    if (!BST) { // 若原树为空,生成并返回一个结点的二叉搜索树
        BST = { data: X, left: null, right: null };
    } else { // 开始找要插入元素的位置
        if (X < BST.data) { // 递归插入左子树
            BST.left = insert(X, BST.left);
        } else if (X > BST.data) { // 递归插入右子树
            BST.right = insert(X, BST.right);
        } // else X已经存在,什么都不做
    }
    return BST;
}
1
2
3
4
5
6
7
8
9
10
11
12

# 二叉搜索树的删除

考虑三种情况

  1. 要删除的是叶节点:直接删除,并再修改其父节点指针 ---置为null;
  2. 要删除的结点只有一个孩子结点: 将其父结点的指针指向要删除结点的孩子结点;
  3. 要删除的结点有左、右两棵子树:用另一结点替代被删除结点:右子树的最小元素 或者 左子树的最大元素

二叉搜索树的删除实现

function deleteNode(X, BST) {
    let tmp;

    if (!BST) console.log("要删除的元素未找到");
    else if (X < BST.data) {
        BST.left = deleteNode(X, BST.left); // 左子树递归删除
    } else if (X > BST.data) {
        BST.right = deleteNode(X, BST.right); // 右子树递归删除
    } else { // 找到要删除的结点
        if (BST.left && BST.right) { // 被删除结点有左右两个子结点
            tmp = findMin(BST.right); // 在右子树中找最小的元素填充删除结点
            BST.data = tmp.data;
            BST.right = deleteNode(BST.data, BST.right); // 在删除结点的右子树中删除最小元素
        } else { // 被删除结点有一个或无子结点
            tmp = BST;
            if (!BST.left) { // 有右孩子或无子结点
                BST = BST.right;
            } else if (!BST.right) { // 有左孩子或无子结点
                BST = BST.left;
            }
            free(tmp); // 释放被删除结点的空间
        }
    }
    return BST;
}

function findMin(BST) {
    while (BST.left) {
        BST = BST.left;
    }
    return BST;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
编辑 (opens new window)
#数据结构
上次更新: 2025/04/18, 01:42:12
二叉树的遍历
平衡二叉树

← 二叉树的遍历 平衡二叉树→

最近更新
01
GSAP动画库——如何高效写动画
04-17
02
自适应方案PxToRem
09-10
03
性能优化-requestAnimationFrame
08-10
更多文章>
Theme by Vdoing | Copyright © 2019-2025 备案号:京ICP备19058102号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式