Python数据结构之二叉排序树的定义、查找、插入、构造、删除

Python数据结构之二叉排序树

一、定义

二叉排序树(Binary Search Tree,BST),也称为二叉查找树或二叉搜索树,是一种基于二叉树的数据结构,其中每个节点都包含一个键值,且满足:

  • 左子树中所有节点的键值均小于当前节点;
  • 右子树中所有节点的键值均大于当前节点;

这是一种自平衡的数据结构,可以快速地进行查找、插入、删除等操作。

二、查找

查找操作是在二叉排序树中查找某个键值对应的节点。查找过程可以用递归或循环实现。

递归实现

class TreeNode:
    def __init__(self, val=None):
        self.val = val
        self.left = None
        self.right = None

class BST:
    def __init__(self):
        self.root = None

    def search(self, val, node):
        if node is None or node.val == val:
            return node
        elif node.val > val:
            return self.search(val, node.left)
        else:
            return self.search(val, node.right)

这里在BST类中定义了一个search方法,采用了递归的方式。如果当前节点为空或者当前节点的值等于要查找的值,则返回当前节点。否则,如果当前节点的值大于要查找的值,则向左子树递归查找;如果当前节点的值小于要查找的值,则向右子树递归查找。

循环实现

class BST:
    def __init__(self):
        self.root = None

    def search(self, val):
        node = self.root
        while node is not None and node.val != val:
            if node.val > val:
                node = node.left
            else:
                node = node.right
        return node

这里在BST类中定义了一个search方法,采用了循环的方式。首先将node指向BST的根节点,然后在循环中判断node是否为空或者node的值是否等于要查找的值。如果是,则返回node;否则,如果node的值大于要查找的值,则将node指向node的左子节点;如果node的值小于要查找的值,则将node指向node的右子节点。

三、插入

插入操作是在二叉排序树中插入一个键值对应的节点。插入过程可以用递归或循环实现。

递归实现

class BST:
    def __init__(self):
        self.root = None

    def insert(self, val, node):
        if node is None:
            node = TreeNode(val)
        elif node.val > val:
            node.left = self.insert(val, node.left)
        elif node.val < val:
            node.right = self.insert(val, node.right)
        return node

这里在BST类中定义了一个insert方法,采用了递归的方式。首先判断当前节点是否为空,如果是,则创建一个新的节点并返回;否则,如果当前节点的值大于要插入的值,则递归插入到左子树;如果当前节点的值小于要插入的值,则递归插入到右子树。

示例:

tree = BST()
tree.root = tree.insert(2, tree.root)
tree.insert(1, tree.root)
tree.insert(3, tree.root)

这里创建了一棵二叉排序树,然后依次插入了3个节点,其值分别为2、1、3。

循环实现

class BST:
    def __init__(self):
        self.root = None

    def insert(self, val):
        node = self.root
        prev = None
        while node is not None:
            prev = node
            if node.val > val:
                node = node.left
            elif node.val < val:
                node = node.right
            else:
                return self.root
        new_node = TreeNode(val)
        if prev is None:
            self.root = new_node
        elif prev.val > val:
            prev.left = new_node
        else:
            prev.right = new_node
        return self.root

这里在BST类中定义了一个insert方法,采用了循环的方式。首先将node指向BST的根节点,prev指向node的父节点,然后在循环中判断node是否为空。如果是,则创建一个新的节点并根据val的大小插入到prev的左子节点或右子节点。

示例:

tree = BST()
tree.insert(2)
tree.insert(1)
tree.insert(3)

这里创建了一棵二叉排序树,然后依次插入了3个节点,其值分别为2、1、3。

四、构造

构造操作是从一个键值的列表中构造出一棵二叉排序树。构造过程可以用递归或循环实现。

递归实现

class BST:
    def __init__(self):
        self.root = None

    def construct(self, values):
        for val in values:
            self.root = self.insert(val, self.root)

这里在BST类中定义了一个construct方法,采用了递归的方式。首先遍历values中的每一个值,然后递归插入到BST中。

示例:

tree = BST()
tree.construct([2, 1, 3])

这里创建了一棵二叉排序树,其值分别为2、1、3。

循环实现

class BST:
    def __init__(self):
        self.root = None

    def construct(self, values):
        for val in values:
            new_node = TreeNode(val)
            node = self.root
            prev = None
            while node is not None:
                prev = node
                if node.val > val:
                    node = node.left
                elif node.val < val:
                    node = node.right
                else:
                    break
            if prev is None:
                self.root = new_node
            elif prev.val > val:
                prev.left = new_node
            else:
                prev.right = new_node

这里在BST类中定义了一个construct方法,采用了循环的方式。首先遍历values中的每一个值,然后依次插入到BST中。

示例:

tree = BST()
tree.construct([2, 1, 3])

这里创建了一棵二叉排序树,其值分别为2、1、3。

五、删除

删除操作是在二叉排序树中删除某个键值对应的节点。主要包含3种情况:

  • 要删除的节点没有子节点;
  • 要删除的节点只有一个子节点;
  • 要删除的节点有两个子节点;

情况一和情况二

情况一和情况二的解决方法相同。如果要删除的节点没有子节点,则直接将其删除;如果要删除的节点只有一个子节点,则将其子节点移到其原来的位置。这里的代码实现比较简单,这里只展示递归实现。

class BST:
    def __init__(self):
        self.root = None

    def delete(self, val, node):
        if node is None:
            return node
        if node.val > val:
            node.left = self.delete(val, node.left)
        elif node.val < val:
            node.right = self.delete(val, node.right)
        else:
            if node.left is None:
                return node.right
            elif node.right is None:
                return node.left
            else:
                min_node = self.find_min(node.right)
                node.val = min_node.val
                node.right = self.delete(min_node.val, node.right)
        return node

    def find_min(self, node):
        while node.left is not None:
            node = node.left
        return node

这里在BST类中定义了一个delete方法,采用了递归的方式。如果当前节点为空,则返回;如果当前节点的值大于要删除的值,则继续递归删除它的左子节点;如果当前节点的值小于要删除的值,则继续递归删除它的右子节点;如果当前节点的值等于要删除的值,则判断当前节点是否有左右子节点。如果没有子节点,则直接返回None;如果只有一个子节点,则返回这个子节点;如果有两个子节点,则找到右子树中最小的节点替换当前节点的值,并递归删除这个最小节点。

情况三

情况三需要特殊处理。首先找到要删除的节点的右子树中最小的节点代替要删除的节点,并从右子树中递归删除这个最小节点。这里的代码实现比较复杂,这里只展示递归实现。

class BST:
    def __init__(self):
        self.root = None

    def delete(self, val, node):
        if node is None:
            return node
        if node.val > val:
            node.left = self.delete(val, node.left)
        elif node.val < val:
            node.right = self.delete(val, node.right)
        else:
            if node.left is None:
                return node.right
            elif node.right is None:
                return node.left
            else:
                min_node = self.find_min(node.right)
                node.val = min_node.val
                node.right = self.delete(min_node.val, node.right)
        return node

    def find_min(self, node):
        while node.left is not None:
            node = node.left
        return node

这里在BST类中定义了一个delete方法,采用了递归的方式。如果当前节点为空,则返回;如果当前节点的值大于要删除的值,则继续递归删除它的左子节点;如果当前节点的值小于要删除的值,则继续递归删除它的右子节点;如果当前节点的值等于要删除的值,则判断当前节点是否有左右子节点。如果没有子节点,则直接返回None;如果只有一个子节点,则返回这个子节点;如果有两个子节点,则找到右子树中最小的节点替换当前节点的值,并递归删除这个最小节点。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python数据结构之二叉排序树的定义、查找、插入、构造、删除 - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • Java数据结构之图的两种搜索算法详解

    Java数据结构之图的两种搜索算法详解 引言 图是现实世界中最为普遍的现象之一,因此对于图的分析和操作是计算机科学和工程中最为重要的问题之一。在本文中,我们将对图结构的两种搜索算法进行详细讨论和研究,这些算法是图论研究的基本工具。 图的定义 在计算机科学和数学领域中,图是由若干个节点(或称为顶点)和它们之间的边组成的一种数据结构。 图的两种搜索算法 图的搜索…

    数据结构 2023年5月17日
    00
  • C语言深入浅出讲解顺序表的实现

    C语言深入浅出讲解顺序表的实现 顺序表简介 顺序表是一种线性表的存储结构,它是由连续的内存空间来存储线性表中的元素。 顺序表的特点是支持查找、插入和删除操作,操作效率较高,但需要提前分配足够大的内存空间。当顺序表空间不足时,需要扩容,移动数据较为麻烦。 顺序表的实现 数据结构定义 顺序表的数据结构定义包含以下几个成员: 数据元素数组 data,存储线性表中的…

    数据结构 2023年5月17日
    00
  • 线段树好题! P2824 [HEOI2016/TJOI2016]排序 题解

    题目传送门 前言 线段树好题!!!!咕咕了挺久的一道题目,很早之前就想写了,今天终于找了个时间A掉了。 题意 给定一个 \(1\) 到 \(n\) 的排列,有 \(m\) 次操作,分两种类型。1.0 l r表示将下标在 \([l, r]\) 区间中的数升序排序。2.1 l r表示将下标在 \([l, r]\) 区间中的数降序排序。给定一个数 \(q\) 询问…

    算法与数据结构 2023年4月17日
    00
  • 李航统计学习概述

    监督学习 感知机 概念: 感知机模型的基本形式是: \(f(x) = sign(w \cdot x + b)\) 其中,\(x\) 是输入样本的特征向量,\(w\) 是权值向量,\(b\) 是偏置量,\(w \cdot x\) 表示向量 \(w\) 和 \(x\) 的点积。\(sign\) 函数表示符号函数,当输入大于 0 时输出 1,否则输出 -1。 要求…

    算法与数据结构 2023年4月25日
    00
  • 【ACM数论】和式变换技术,也许是最好的讲解之一

    在做数论题时,往往需要进行和式变换,然后变换成我们可以处理的和式,再针对和式做筛法、整除分块等操作。 本文将介绍一些常见的和式变换技术。 以下出现的概念大部分为个人总结,未必是学术界/竞赛界的统一说法,有不严谨的地方请谅解。 ? 作者:Eriktse? 简介:19岁,211计算机在读,现役ACM银牌选手?力争以通俗易懂的方式讲解算法!❤️欢迎关注我,一起交流…

    算法与数据结构 2023年4月17日
    00
  • C语言数据结构深入探索顺序表

    C语言数据结构深入探索顺序表攻略 一、概述 顺序表是一种线性结构,是计算机程序中最常见的数据结构之一。在C语言中,顺序表可以用数组来实现。本篇文章将深入讲解顺序表的原理和实现方法,帮助读者加深对顺序表的理解,并掌握如何用C语言代码实现顺序表。 二、顺序表的定义和特点 顺序表是指用一组地址连续的存储单元依次存储线性表中的各个元素,用于表示具有相同数据类型的n个…

    数据结构 2023年5月17日
    00
  • C语言 数据结构堆排序顺序存储(升序)

    C语言 数据结构堆排序顺序存储(升序)攻略 1. 堆排序概述 堆排序是一种常见的排序算法,通过构建最大堆或最小堆来实现排序。本文介绍的是使用顺序存储方式实现的最大堆排序,也就是升序排序。 2. 最大堆的定义和实现 最大堆指的是堆结构中父节点的值大于子节点的值,根节点的值最大。对于一棵完全二叉树,若父节点的下标为i,则其左子节点的下标为2i+1,右子节点的下标…

    数据结构 2023年5月17日
    00
  • C语言数据结构中定位函数Index的使用方法

    C语言的数据结构中,定位函数Index的使用方法主要涉及到数组和指针的相关操作。Index函数的作用是在数组中查找对应的元素,返回该元素的索引位置。以下是详细攻略: 一、Index函数的用法 Index函数的原型如下: void *index(const void *s, int c, size_t n); 其中,参数含义如下: s: 要查找的数组 c: 要…

    数据结构 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部