二叉查找树(BST)的基本概念及常用操作

2023-11-16

二叉查找树

二叉查找树(Binary Search Tree),也称二叉搜索树、有序二叉树(ordered binary tree),排序二叉树(orted binary tree),是指一棵空树或者具有下列性质的二叉树:

  • 若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值;
  • 若任意节点的右子树不空,则右子树上所有节点的值均大于它的根节点的值;
  • 任意节点的左、右子树也分别为二叉查找树;
  • 没有键值相等的节点

二叉查找树相比于其他数据结构的优势在于查找、插入的时间复杂度较低,均为O(log n)。二叉查找树是基础性数据结构,用于构建更为抽象的数据结构,如集合、multiset、关联数组等。

常用操作

定义树的节点如下:

class Node:
    def __init__(self, val):
        self.val = val
        self.left = None
        self.right = None
1. 查找

在二叉搜索树 b b 中查找xx的过程为:

  1. 若b是空树,则搜索失败,否则:
  2. 若x等于b的根节点的数据域之值,则查找成功;否则:
  3. 若x小于b的根节点的数据域之值,则递归搜索左子树;否则:
  4. 递归查找右子树

使用python实现如下:

def search(root, val):
    if root == None:
        return False, None
    elif val > root.val:
        return search(root.right, val)
    elif val < root.val:
        return search(root.left, val)
    else:
        return True, root
2. 插入

向一个二叉搜索树 b b 中插入一个节点ss的算法,过程为:

  • 若b是空树,则将s所指结点作为根节点插入,否则:
  • 若s.val等于b的根节点的数据域之值,则返回,否则:
  • 若s.val小于b的根节点的数据域之值,则把s所指节点插入到左子树中,否则:
  • 把s所指节点插入到右子树中(新插入节点总是叶子节点)
def insert(self, root, node):
    """insert inplace"""
    if root ==  None:
        root = node
        return
    if node.val == root.val:
        return
    elif node.val > root.val:
        self.insert(root.right, node)
    else:
        self.insert(root.left, node)
3. 删除

二叉搜索树的删除操作分三种情况讨论:
1. 如果待删除的节点是叶子节点,那么可以立即被删除,如下图所示:
例:删除数据为16的节点,是叶子节点,可以直接删除
这里写图片描述
2. 如果有一个子节点,要将下一个子节点上移到当前节点,即替换之
例:删除数据为25的节点,它下面有唯一一个子节点35, 上移到替换之
这里写图片描述
3. 如果有两个子节点,则将其右子树的最小数据代替此节点的数据,并将其右子树的最小数据删除,如下图所示
例:删除节点数据为5的节点,找到被删除节点右子树的最小节点。需要一个临时变量successor,将11节点下面的子节点进行查询,找到右子树最小节点7,并把右子树最小节点7替换被删除节点,维持二叉树结构。如下图
这里写图片描述

class solution:
    def deleteNode(self, root, key):
        """
        :type root: TreeNode
        :type key: int
        :rtype: TreeNode
        """
        if root == None:
            return None
        if key < root.val:
            root.left = self.deleteNode(root.left, key)
        elif key > root.val:
            root.right = self.deleteNode(root.right, key)
        else:
            if root.left == None:
                return root.right
            elif root.right == None:
                return root.left
            else:
                min_node = self.findMinNode(root.right)
                root.val = min_node.val
                root.right = self.deleteNode(root.right, root.val)
        return root

    def findMinNode(self, node):
        while node.left:
            node = node.left
        return node
4. 遍历

可以采用前序,中序,后序来遍历该二叉搜索树,或者使用广度优先搜索的方式。这里用中序遍历来实现,可以保证按从小到大的顺序打印。

def traverse_binary_tree(root):
    if root is None:
        return
    traverse_binary_tree(root.left)
    print(root.value)
    traverse_binary_tree(root.right)
5. 构造一颗二叉查找树

用一组数值建造一棵二叉查找树的同时,也把这组数值进行了排序。其最差时间复杂度为 O(n2) O ( n 2 ) 。例如,若该组数值经是有序的(从小到大),则建造出来的二叉查找树的所有节点,都没有左子树

def build_binary_tree(values):
    tree = None
    for v in values:
        tree = insert(tree, Node(v))
    return tree

性能分析

查找:最佳情况 Olog(n) O l o g ( n ) , 最坏情况 O(n) O ( n )
插入:最佳情况 Olog(n) O l o g ( n ) , 最坏情况 O(n) O ( n )
删除:最佳情况 Olog(n) O l o g ( n ) , 最坏情况 O(n) O ( n )

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

二叉查找树(BST)的基本概念及常用操作 的相关文章

  • 有趣的数据结构算法16——线索二叉树的构建

    有趣的数据结构算法16 线索二叉树的构建 什么是线索二叉树 线索二叉树的实现形式 线索二叉树的代码实现 线索二叉树的初始化 线索的串联 全部实现代码 GITHUB下载连接 深度遍历不仅仅有递归的方法噢 还有通过建立线索二叉树进行遍历的方法
  • 两个二叉树的合并

    将给定两个二叉树 想象当你将它们中的一个覆盖到另一个上时 两个二叉树的一些节点便会重叠 你需要将他们合并为一个新的二叉树 合并的规则是如果两个节点重叠 那么将他们的值相加作为节点合并后的新值 否则不为 NULL 的节点将直接作为新二叉树的节
  • 【leetcode】----102二叉树的层序遍历

    102二叉树的层序遍历 给你一个二叉树 请你返回其按 层序遍历 得到的节点值 即逐层地 从左到右访问所有节点 示例 二叉树 3 9 20 null null 15 7 3 9 20 15 7 返回其层次遍历结果 3 9 20 15 7 BF
  • 二叉树的性质

    二叉树的性质以及满二叉树 完全二叉树 性质一 在二叉树的第i层 最多有2的 i 1 次方个结点i gt 1 性质二 深度为k的二叉树上最多有含有2的k次方 1个结点 k gt 1 性质三 对于任何一个二叉树 若它含有n0个叶子结点 n2个度
  • 剖析高性能队列Disruptor背后的数据结构和算法

    本文是学习算法的笔记 数据结构与算法之美 极客时间的课程 Disruptor 是一种内存消息队列 它经Java 中另外一个非常常用的内存消息队列 ArrayBlockQueue ABS 的性能 要高出一个数量级 可以算得上是最快的内存消息队
  • 【数据结构】Trie 字典树

    数据结构源码 实现类 import java util TreeMap public class Trie private class Node public boolean isWord public TreeMap
  • LeetCode——二叉树

    二叉树 二叉树概念和性质 104 二叉树的的最大深度 递归 98 验证二叉搜索树 中序遍历 101 对称二叉树 代码比较精巧 不好理解 102 二叉树的层序遍历 中等 参考题解 自己码的代码 108 将有序数组转换为二叉搜索树 递归 剑指
  • (Java)leetcode-236 Lowest Common Ancestor of a Binary Tree(二叉树的最近公共祖先)

    题目描述 给定一个二叉树 找到该树中两个指定节点的最近公共祖先 百度百科中最近公共祖先的定义为 对于有根树 T 的两个结点 p q 最近公共祖先表示为一个结点 x 满足 x 是 p q 的祖先且 x 的深度尽可能大 一个节点也可以是它自己的
  • 两数之和 暴力美学 哈希表

    1 两数之和 给定一个整数数组 nums 和一个整数目标值 target 请你在该数组中找出 和为目标值 的那 两个 整数 并返回它们的数组下标 leetcode 你可以假设每种输入只会对应一个答案 但是 数组中同一个元素在答案里不能重复出
  • [课程复习] 数据结构之线性表、树、图、查找、排序经典算法复习

    作者最近在复习考博 乘此机会分享一些计算机科学与技术 软件工程等相关专业课程考题 一方面分享给考研 考博 找工作的博友 另一方面也是自己今后完成这些课程的复习资料 同时也是在线笔记 基础知识 希望对您有所帮助 不喜勿喷 无知 乐观 低调 谦
  • 华为OD德科面试+机试记录

    一 机试 6 25 三道编程题 难度偏中 由于时间久远 只记得其中两道题目 1 找车位 动态规划 2 题目不记得了 后面如果找到会补充 双指针 3 高效的任务规划 动态规划 第一题和第二题是做出来了 第三题做出来一点点 当时时间不够 没想出
  • 【数据结构】Binary Search Tree(BST) 二分搜索树

    数据结构源码 实现类 import java util import java util LinkedList import java util Queue import java util Stack 二分搜素树 BST param
  • 前缀、中缀、后缀表达式和二叉树

    概念 前缀表达式 Prefix Notation 是指将运算符写在前面操作数写在后面的不包含括号的表达式 而且为了纪念其发明者波兰数学家Jan Lukasiewicz 所以前缀表达式也叫做 波兰表达式 后缀表达式 Postfix Notat
  • 哈希表设计思想及实现

    哈希表设计思想及实现 定义 哈希表在 算法4 这本书中是这么介绍的 哈希表其实又叫散列表 是算法在时间和空间上做出权衡的经典例子 如果一个表所有的键都是小整数 我们就可以用一个数组来实现无序的符号表 将键作为数组的索引而数组中i出存储的值就
  • CH7-查找

    文章目录 1 查找的基本概念 2 线性表的查找 2 1 顺序查找 线性查找 算法2 1 0 类型定义 算法2 1 1 顺序查找 算法2 1 2 改进后的顺序查找 性能分析 2 2 折半查找 二分或对分查找 算法2 2 1 非递归算法 算法2
  • 树的广度优先遍历与深度优先遍历算法

    1 树的广度优先遍历算法 广度优先遍历算法 又叫宽度优先遍历 或横向优先遍历 是从根节点开始 沿着树的宽度遍历树的节点 如果所有节点均被访问 则算法中止 如上图所示的二叉树 A 是第一个访问的 然后顺序是 B C 然后再是 D E F G
  • 关于数据结构中的叶节点和二度节点的关系(通俗的理解)。

    简单记录一下自己的一些地方和对于这个问题我的一些见解 有说的不好的地方欢迎指正 这里只给出一种理解 另一种利用公式进行理解的 我就不写了 因为csdn里面太多了 先说结论 叶节点的数目 二度节点 1 首先来看这张图 可以看到这个图大体是包含
  • JAVA实现二叉树的前、中、后序遍历(递归与非递归)

    最近在面试中遇到过问到二叉树后序遍历非递归实现的方法 之前以为会递归的解决就OK 看来还是太心存侥幸 在下一次面试之前 特地整理一下这个问题 首先二叉树的结构定义 java代码如下 public class Node private int
  • 算法:深度优先遍历和广度优先遍历

    什么是深度 广度优先遍历 图的遍历是指 从给定图中任意指定的顶点 称为初始点 出发 按照某种搜索方法沿着图的边访问图中的所有顶点 使每个顶点仅被访问一次 这个过程称为图的遍历 遍历过程中得到的顶点序列称为图遍历序列 图的遍历过程中 根据搜索
  • 【LeetCode刷题笔记】位运算

    231 2 的幂 解题思路 1 除法 不断循环判断 如果能被 2 整除 就不断除以 2 直到不能被 2 整除为止 最后结果如果是 1

随机推荐

  • Rxjava初步理解

    本质就是通过回调实现 Observable被观察对像 成员变量onSubscribe Subscriber 观察对象 订阅 Observable subscribe先调用Subscriber onStart 然后调用onSubscribe中
  • 如何怎样安装nvm

    使用宝塔的Nodejs环境体验比较差 如果要完全使用命令行 应该如何玩转呢 今天我们简要介绍下步骤 方便大家自己使用 首先 我们创建一个文件install sh 然后将下面代码复制粘贴进去 usr bin env bash this ens
  • PowerDesigner生成Excel版本的数据库文件

    File pdm2excel txt Title pdm export to excel Purpose To export the tables and columns to Excel Model Physical Data Model
  • Python - Numpy库的使用(简单易懂)

    目录 numpy多维数组 数组的创建 1 array函数创建数组对象 2 通过arange linspace函数创建等差数组对象 3 通过logspace函数创建等比数列数组 函数 zeros ones diag eye full nump
  • 区块链技术的特点

    区块链技术是一种去中心化的分布式账本技术 它有以下优势和应用场景 1 去中心化 区块链是一种去中心化的技术 因此可以在不需要任何中心机构或者第三方的情况下 实现信息交换和价值转移 这使得它可以在许多领域得到应用 2 可追溯性 区块链技术可以
  • 为什么设置不了这是一台家用计算机,图文演示win10专业版更改不了这是一台家庭计算机的详尽处理步骤...

    win10系统从发布到现在已经好多年了 各种问题也得到了解决 但是今天还是有用户说出现了win10专业版更改不了这是一台家庭计算机的问题 很多网友都没有关于win10专业版更改不了这是一台家庭计算机的问题的处理经验 如果你咨询很多人都不知道
  • 520表白季——你表白成功了吗

    晓玲 小A 你昨天不是向D君表白了吗 今天这是怎么了 怎么还一副伤心的样子 泪眼汪汪的 小A 5555 晓玲姐姐 D君他居然说我是花心大萝卜 我明明就只喜欢他一个啊 晓玲 这样啊 走 我们去找定位帮帮忙 Ctrl G调出定位对话框 gt 定
  • JS 正则表达式截取指定字符的前面后面的内容

    1 js截取两个字符串之间的内容 let str web辣鸡工程师前端 str str match web S 前端 1 alert str 辣鸡工程师 2 js截取某个字符串前面的内容 var str 内容 截取字符串 str str m
  • 如何在vue中引入百度地图

    1 进入百度地图开放平台官网 进行实名认证 https lbsyun baidu com 2 完成实名认证后 进入控制台 3 进入应用管理 gt 我的应用 gt 创建应用 4 根据应用场景更改应用类型 5 白名单填写 gt 提交 6 这样就
  • 机器人编程课必要性

    机器人编程课必要性 说起小孩的学习 想必家长们都是非常的有发言权的 很多的家长想要孩子去学习机器人编程的课程 但是有的家长对于机器人编程课必要性并不是特别的清楚 他们不知道孩子学习机器人编程有啥好处 今天我们就一起来了解一下机器人编程课必要
  • 年末盘点,2021年最值得推荐的10个提高开发效率工具,程序员必备

    程序员的日常工作中 好用的工具往往能让我们事半功倍 极大提升我们的开发效率 接下来分享下我平时工作中经常使用的一些工具 也欢迎大家在评论区给我推荐一些好用的工具软件 一起学习 一 网络抓包工具 1 Proxyman 平时自己编写的程序网络通
  • MySQL 多种查询方法

    这里写目录标题 查询 1 单表查询 1 选择表中的若干列 2 选择表中的若干元组 3 order by子句 4 聚集函数 5 group by分组 2 连接查询 1 等值与非等值连接查询 2 自身连接 3 外连接 4 多表连接 3 嵌套查询
  • CSS学习(六)

    定位 为什么需要定位 提问 以下情况使用标准流或者浮动能实现吗 某个元素可以自由的在一个盒子内移动位置 并且压住其他盒子 当我们滚动窗口的时候 盒子是固定屏幕某个位置的 以上效果 标准流或浮动都无法快速实现 此时需要定位来实现 所以 浮动可
  • vscode 检查c代码语法和补全_VScode下搭配ESLint、TSLint、stylelint的代码检查配方

    使用VScode打开项目时 避免项目路径过深 尽量做到开发a项目就打开a项目 如 dir path path a这样的路径 不要vscode打开 dir来开发 a 因为可能会导致eslint的一些提示出现不准确的现象 关键词 ESLint配
  • tensorflow4:创建一个简单的强化学习游戏

    Deep Q Network是DeepMind最早 2013年 提出来的 是深度强化学习方法 最开始AI什么也不会 通过给它提供游戏界面像素和分数 慢慢把它训练成游戏高手 这里首先给出一个基本的游戏例子 然后再给出强化学习方法 1 基本游戏
  • elementui 计数器

    输入值超过规定的最大值 比如999 输入1000时 输入后 直接提交表单 中间计数器会自动把1000转化为999 再提交 测试人员说没有出现 不能超过3位数字的提示 解决办法 把min和max去掉 再写自定义验证规则就可以了 计数器自动转化
  • JavaScript:iterable类型

    遍历Array可以采用下标循环 遍历Map和Set就无法使用下标 为了统一集合类型 ES6标准引入了新的iterable类型 Array Map和Set都属于iterable类型 具有iterable类型的集合可以通过新的for of循环来
  • 向量积(叉积)及其计算

    定义 两个向量a和b的 向量积 外积 叉积 是一个向量 记作a b 这里 并不是乘号 只是一种表示方法 与 不同 也可记做 若a b不共线 则a b的模是 a b a b sin a b a b的方向是 垂直于a和b 且a b和a b按这个
  • 【Linux】基于单例模式懒汉实现方式的线程池

    需要云服务器等云产品来学习Linux的同学可以移步 gt 腾讯云 lt gt 阿里云 lt gt 华为云 lt 官网 轻量型云服务器低至112元 年 新用户首次下单享超低折扣 目录 一 LockGuard hpp 二 Task hpp 三
  • 二叉查找树(BST)的基本概念及常用操作

    二叉查找树 二叉查找树 Binary Search Tree 也称二叉搜索树 有序二叉树 ordered binary tree 排序二叉树 orted binary tree 是指一棵空树或者具有下列性质的二叉树 若任意节点的左子树不空