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数据结构之二叉排序树的实现 二叉排序树(Binary Sort Tree)是一种特殊的二叉树结构,它的每个结点都包含一个关键字,并满足以下性质: 左子树中所有结点的关键字都小于根结点的关键字; 右子树中所有结点的关键字都大于根结点的关键字; 左右子树也分别为二叉排序树。 这种结构有助于实现快速的查找、插入和删除操作。在此,我们将展示一种实现二叉排序树…

    数据结构 2023年5月17日
    00
  • C语言数据结构二叉树简单应用

    C语言数据结构二叉树简单应用攻略 1. 什么是二叉树? 二叉树(Binary Tree)是一种树形结构,它的每个节点最多包含两个子节点,它是非线性数据结构,可以用来表示许多问题,例如家族关系、计算机文件系统等等。 2. 二叉树的基本操作 二叉树的基本操作包括插入、删除、查找等等,本攻略主要讲解插入和查找的实现。 插入操作的代码如下: // 二叉树的插入操作 …

    数据结构 2023年5月17日
    00
  • C++深入分析讲解链表

    C++深入分析讲解链表 链表概述 链表是数据结构中最基本和重要的一种,它的实现可以分为链表的节点和链表的指针。每个节点都记录着链表中的一个元素,并带有一个指向下一个节点的指针,这样就可以通过遍历指针,达到遍历链表的目的。 链表数据结构 在C++中,链表可以通过结构体或者类来实现,比如以下这个结构体实现的单向链表: struct Node { int data…

    数据结构 2023年5月17日
    00
  • Java常见数据结构面试题(带答案)

    Java常见数据结构面试题(带答案)完整攻略 介绍 在Java面试中,数据结构不可避免地成为一部分的考察内容。因此,掌握Java常见数据结构,对于提高面试成功率十分必要。本篇攻略将会介绍常见的Java数据结构,并提供相应的面试题目和答案,希望可以帮助面试者在面试当中更好地展示自己的实力。 目录 结构体 数组 链表 栈 队列 树 哈希表 结构体 在Java中并…

    数据结构 2023年5月17日
    00
  • C语言数据结构实例讲解单链表的实现

    C语言数据结构实例讲解单链表的实现 单链表是一种线性的数据结构,它由一系列节点组成,每个节点都包含一个数据域和一个指向下一个节点的指针域。单链表常用于需要频繁插入删除元素的场景中。 单链表的数据结构设计 在C语言中,我们可以使用结构体来定义单链表的节点: typedef struct node { int data; // 数据域 struct node* …

    数据结构 2023年5月17日
    00
  • C语言全面梳理结构体知识点

    C语言全面梳理结构体知识点 什么是结构体? 结构体是一种自定义的数据类型,它可以包含多个不同类型的成员变量,并且这些成员变量可以通过一个变量名来访问。结构体的定义需要使用关键字struct,并且需要指定结构体的类型名和成员变量。例如: struct Person { char name[20]; int age; float height; }; 以上代码就…

    数据结构 2023年5月17日
    00
  • 「分治」黑白棋子的移动

    本题为3月23日23上半学期集训每日一题中A题的题解 题面 题目描述 有2n个棋子(n≥4)排成一行,开始位置为白子全部在左边,黑子全部在右边,如下图为n=5的情形: ○○○○○●●●●● 移动棋子的规则是:每次必须同时移动相邻的两个棋子,颜色不限,可以左移也可以右移到空位上去,但不能调换两个棋子的左右位置。每次移动必须跳过若干个棋子(不能平移),要求最后能…

    算法与数据结构 2023年4月18日
    00
  • C语言多维数组数据结构的实现详解

    C语言多维数组数据结构的实现详解 多维数组的定义 多维数组是由若干行和若干列构成的数据类型,它由多个一维数组组成。在C语言中,多维数组的定义和一维数组十分相似,只是在数组定义中增加了方括号以表示维数。 下面是一个二维数组的定义: int arr[3][4]; 上述代码定义了一个3行4列的二维数组,标识符为arr,它包含12个元素。其中arr[0][0]到ar…

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