【python数据结构】二叉搜索树

二叉搜索树

1. 定义

​ 二叉搜索树(BST)也称二叉排序树或二叉查找树

二叉搜索树:一棵二叉树,可以为空;如果不为空,满足以下性质:

  •     非空左子树的所有键值小于其根结点的键值
  •     非空右子树的所有键值大于其根结点的键值
  •     左、右子树都是二叉搜索树

2. 特殊函数

  •     BinTree Find(ElementType X,BinTree BST):从二叉搜索树 BST 中查找元素 X,返回其所在结点地址
  •     BinTree FindMin(BinTree BST):从二叉搜索树 BST 中查找并返回最小元素所在结点的地址
  •     BinTree FindMax(BinTree BST):从二叉搜索树 BST 中查找并返回最大元素所在结点的地址
  •     BinTree Insert(ElementType X,BinTree BST):插入一个元素进 BST
  •     BinTree Delete(ElementType X,BinTree BST):从 BST 中删除一个元素

1. 查找

    查找从根结点开始,如果树为空,返回 NULL
    若搜索树不为空,则根结点键值和 X 进行比较,并进行不同处理:

  •         若 X 小于根结点键值,在左子树中继续查找
  •         若 X 大于根结点键值,在右子树中继续查找
  •         如 X 等于根节点键值,查找结束,返回指向此结点的指针

2. 查找最大和最小元素

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

3. 删除

删除的三种情况:

  •     要删除的是叶结点:直接删除,并将其父结点指针置为 NULL
  •     要删除的结点只有一个孩子结点:将其父结点的指针指向要删除结点的孩子结点
  •     要删除的结点有左、右两棵子树:用右子树的最小元素或左子树的最大元素替代被删除结点

4. 代码实现

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @File  : 二叉搜索树.py
# @Date  : 2019/3/28 0028
# @Contact : [email protected] 
# @Author: DeepMan


"""
分别在左右子树中进行递归查找
当相等的时候返回
"""
from Tree import *


node_list = [89 ,8 ,64 ,64 ,9, 49, 65 ,146, 4, 61, 5,46]

# 创建一棵树
tree = BinaryTree(10)
for node in node_list:
    tree.insert(node, tree)


# 递归查找
def find(x, BST):
    if not BST: # 如果树为空 则直接return
        return
    if x < BST.data:
        return find(x, BST.left)
    if x > BST.data:
        return find(x, BST.right)
    if x == BST.data:
        return BST
# print(find(10, tree).right.data)

# 非递归查找  对于上面这种 尾递归 可以使用循环来实现
def iterfind(x, BST):

    while(BST):
        if x < BST.data:
            BST = BST.left
        if x > BST.data:
            BST = BST.right
        if x == BST.data:
            return BST
    return None

# print(iterfind(10, tree).right.data)

# 查找最小值的递归实现**************************************************
def findmin(BST): # 最小值在最左边
    if not BST:
        return None
    elif BST.left:
        return  findmin(BST.left)
    else:
        return BST
# print(findmin(tree).data)


# 查找最大值 的 非递归实现 最大元素在最右边
def iterfindmax(BST):

    while BST.right:
        BST = BST.right
    return BST
# print(iterfindmax(tree).data)


# 插入元素的操作
def insert(valve, BST):
    """插入数据, 首先要找到对应插入的位置,再进行插入操作
    :param valve:
    :param BST:
    :return:
    """
    if not BST:
        BST = BinaryTree(valve)
    else:
        if valve < BST.data:
            BST.left = insert(valve, BST.left)
        if valve > BST.data:
            BST.right = insert(valve, BST.right)

        # 如果已经存在则什么都不做

    return BST

# print(iterfindmax(insert(256, tree)).data)


# 二叉树的删除 ***************************************************************
"""
对于要删除节点包含左右儿子节点的情况:
1:取右子树中最小的元素替代 (一定在右子树的最左边,没有左儿子)
2: 取左子树中最大的元素替代 (一定在左子树的最右边,没有右儿子)
"""

def delet(x, BST):
    if not BST: # not None  当为None的时候进入
        print("do not find ")
    elif x < BST.data:
        BST.left = delet(x, BST.left)
    elif x > BST.data:
        BST.right = delet(x, BST.right)
    elif x == BST.data: # 这时候就找到了
        if BST.left and BST.right:  # 如果有两个儿子节点 则利用上面的那种情况进行解决
            temp = findmin(BST.right)  # 找到右子树的最小元素进行替代
            BST.data = temp.data
            BST.right = delet(BST.data, BST.right)  # 删除那个最小的节点
        else: # 被删除节点没有子节点 或 只有一个子节点
            if not BST.right:  # 右节点为空
                BST = BST.left
            elif not BST.left: # 左节点为空
                BST = BST.right
    return BST

bst = delet(146, tree)
print(find(146, bst))


发布了21 篇原创文章 · 获赞 12 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_37206602/article/details/88878817
今日推荐