介绍

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

若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值;

若任意节点的右子树不空,则右子树上所有节点的值均大于它的根节点的值;

任意节点的左、右子树也分别为二叉查找树;

没有键值相等的节点。

通常采取二叉链表作为二叉查找树的存储结构。

复杂度

算法

平均

最差

空间

O(n)

O(n)

搜索

O(log n)

O(n)

插入

O(log n)

O(n)

删除

O(log n)

O(n)

查找步骤

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

若b是空树,则搜索失败,否则:

若x等于b的根节点的数据域之值,则查找成功;否则:

若x小于b的根节点的数据域之值,则搜索左子树;否则:

查找右子树。

插入步骤

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

若b是空树,则将s所指节点作为根节点插入,否则:

若s->data等于b的根节点的数据域之值,则返回,否则:

若s->data小于b的根节点的数据域之值,则把s所指节点插入到左子树中,否则:

把s所指节点插入到右子树中。(新插入节点总是叶子节点)

删除步骤

从 BST 中删除节点比插入节点难度更大。因为删除一个非叶子节点,就必须选择其他节点来填补因删除节点所造成的树的断裂。如果不选择节点来填补这个断裂,那么就违背了 BST 的性质要求。

删除节点算法的第一步是定位要被删除的节点,这可以使用前面介绍的查找算法,因此运行时间为 O(log­2n)。接着应该选择合适的节点来代替删除节点的位置,它共有三种情况需要考虑。

情况 1:若被删除结点为叶子结点,即该节点的左子树和右子树均为空树。由于删去叶子结点不破坏整棵树的结构,则只需修改其双亲结点的指针即可。

情况 2:若被删除结点只有左子树或右子树,此时只要令左子树或右子树直接成为其双亲结点的左子树或右子树即可,作此修改也不破坏二叉查找树的特性。

情况 3:若被删除结点的左子树和右子树均不空,如果被删除节点的右孩子没有左孩子,那么这个右孩子被用来替换被删除节点。因为被删除节点的右孩子都大于被删除节点左子树的所有节点,同时也大于或小于被删除节点的父节点,这同样取决于被删除节点是左孩子还是右孩子。因此,用右孩子来替换被删除节点,符合二叉查找树的性质。如果被删除节点的右孩子有左孩子,就需要用被删除节点右孩子的左子树中的最下面的节点来替换它,就是说,我们用被删除节点的右子树中最小值的节点来替换。

遍历步骤

先序遍历,中序遍历,后序遍历

python

class BinarySearchTree(object):

def __init__(self, data, left=None, right=None, parent=None):

self.data = data

self.left = left

self.right = right

self.parent = parent

class BST(object):

def __init__(self):

self.root = None

self.size = 0

def lenght(self):

return self.size

def find(self, key):

if self.root:

result = self._find(key, self.root)

if result:

return result

else:

return None

else:

None

def _find(self, key, node):

if not node:

return None

elif node.data == key:

return node

elif key < node.data:

return self._find(key, node.left)

else:

return self._find(key, node.right)

def insert(self, key):

node = BinarySearchTree(key)

if not self.root:

self.root = node

self.size += 1

else:

currentNode = self.root

while True:

if key < currentNode.data:

if currentNode.left:

currentNode = currentNode.left

else:

currentNode.left = node

node.parent = currentNode

self.size += 1

break

elif key > currentNode.data:

if currentNode.right:

currentNode = currentNode.right

else:

currentNode.right = node

node.parent = currentNode

self.size += 1

break

else:

break

def findMin(self):

if self.root:

return self._findMin(self.root)

else:

return None

def findMax(self):

if self.root:

currentNode = self.root

while currentNode.right:

currentNode = currentNode.right

return currentNode

else:

return None

def _findMin(self, node):

if node:

currentNode = node

while currentNode.left:

currentNode = currentNode.left

return currentNode

def delete(self, key):

if self.size > 1:

nodeToDelete = self.find(key)

if nodeToDelete:

self._delete(nodeToDelete)

self.size -= 1

else:

raise KeyError('Error, key not in tree')

elif self.size == 1 and self.root.data == key:

self.root = BinarySearchTree(None)

self.size = 0

else:

raise KeyError('Error, key not in tree')

def _delete(self, node):

if not node.left and node.right: #node为树叶

if node == node.parent.left: #node为父节点的左子树

node.parent.left = None

else:

node.parent.right = None

elif node.right and node.left: #node有两个儿子

minNone = self._findMin(node.right)

node.data = minNone.data

self._delete(minNone)

else: #node有一个儿子

if node.left: #node有左儿子

if node.parent and node.parent.left == node: #node为父节点的左子树

node.left.parent = node.parent

node.parent.left = node.left

elif node.parent and node.parent.right == node: #node为父节点的右子树

node.left.parent = node.parent

node.parent.right = node.left

else: # node为根

self.root = node.left

node.left.parent = None

node.left = None

else:

if node.parent and node.parent.left == node:

node.right.parent = node.parent

node.parent.left = node.right

elif node.parent and node.parent.right == node:

node.right.parent = node.parent

node.parent.right = node.right

else:

self.root = node.right

node.right.parent = None

node.right = None

def printTree(self):

if self.size == 0:

print("Empty Tree")

else:

self._printTree(self.root)

def _printTree(self, node):

if node: #中序遍历

self._printTree(node.left)

print(node.data)

self._printTree(node.right)

二叉树查找python_二叉搜索树的python实现相关推荐

  1. 【数据结构】二叉搜索树的python实现

    [数据结构]二叉搜索树的python实现 二叉搜索树是以二叉树来组织的,对于一个二叉搜索树的节点,其左子树节点的元素值都不大于该节点元素值,其右子树节点的元素值都不小于该节点的元素值. 首先定义一个初 ...

  2. C语言判断二叉树是否为二叉搜索树(附完整源码)

    C语言判断二叉树是否为二叉搜索树 C语言判断二叉树是否为二叉搜索树完整源码(定义,实现,main函数测试) C语言判断二叉树是否为二叉搜索树完整源码(定义,实现,main函数测试) #include ...

  3. 树形结构:从二分查找,二叉搜索树寻找最近祖先,从递归到迭代,实现技巧总结

    二分查找,二叉搜索树寻找最近祖先均是典型分治问题,把原问题分成三部分考虑,递归实现简单,迭代实现也比较简单,里面蕴含了一些从从递归到迭代的技巧,注意这里没有使用模拟栈技术. 深究其原因是,这一类型的递 ...

  4. 判定一棵二叉树是否是二叉搜索树

    问题 给定一棵二叉树,判定该二叉树是否是二叉搜索树(Binary Search Tree)? 解法1:暴力搜索 首先说明一下二叉树和二叉搜索树的区别.二叉树指这样的树结构,它的每个结点的孩子数目最多为 ...

  5. 判断二叉树是否为二叉搜索树

    1.题目 给定一棵二叉树的根节点,判断其是否为二叉搜索树. 2.分析 二叉搜索树:每一棵子树的根节点,左子树的值比根节点的值小,右子树的值比根节点的值大. 经典的二叉搜索树是没有重复值的.如果要放重复 ...

  6. c++判断二叉树是否为二叉搜索树_原创 | 好端端的数据结构,为什么叫它SB树呢?...

    点击上方蓝字,关注并星标,和我一起学技术. 大家好,今天给大家介绍一个很厉害的数据结构,它的名字就很厉害,叫SB树,业内大佬往往叫做傻叉树.这个真不是我框你们,而是它的英文缩写就叫SBT. SBT其实 ...

  7. 有序二叉树c语言,二叉搜索树(BST)的实现(C语言)(原创)

    叉搜索树(Binary Search Tree)的一般形式如下图所示,每个节点中的元素大于它的左子树中的所有元素,小于它的右子树中的所有元素.对该图中的二叉树进行中序遍历得到一个从小到大排列的有序序列 ...

  8. C++初阶学习————二叉树进阶(二叉搜索树)

    二叉树进阶 二叉搜索树的概念 二叉搜索树的操作 基本框架 二叉搜索树的插入 二叉搜索树的查找 二叉搜索树的删除 整体代码 循环写法 递归写法 二叉搜索树的应用 二叉搜索树的性能分析 前面的文章介绍过二 ...

  9. 【C++】二叉树进阶(二叉搜索树)

    文章目录 前言 1.二叉搜索树 1-1. 二叉搜索树概念 2.二叉搜索树操作 2-1.树和节点的基本框架 2-2.二叉搜索树的查找 2-3.中序遍历 2-4.二叉搜索树的插入 2-5.二叉搜索树的删除 ...

最新文章

  1. 如何混合编译C语言和C++
  2. 单片机18b20c语言程序,AVR单片机控制DS18B20的示例C程序
  3. CIA困局:天下再无007,AI识别下无处遁行的“特工”们
  4. TTL expired in transit--问题篇~
  5. 前端学习(2984):一文理解数据劫持2
  6. 将已有项目转为se项目_如何将 Java 项目转换成 Maven 项目
  7. thymeleaf学习
  8. Python 之 循环
  9. mysql 存储过程代码_mysql存储过程语法与实例
  10. chrome最强大的浏览器插件推荐,只要你会用其他的插件你可以删除了
  11. idea导入java项目步骤_idea导入javaweb项目
  12. 计算机接口74LS138,搞定138译码器(一),译码器介绍+74LS 138译码器逻辑功能
  13. (四十二)利率互换与货币互换的定价
  14. c# 贪婪匹配 html,C#正则表达式之贪婪模式
  15. 关于设计(一)设计的概念和意义
  16. 工匠精神消失的手机2020:衰落、变局、绝唱、破圈
  17. Android 仿京东淘宝多规格选择
  18. Codeforces Round #694 (Div. 2) F. Strange Housing (贪心思维)
  19. 计算机考研只考一门“软件工程”的院校汇总
  20. “鸡”不可失—— 咕咕机3代VS2代对比测评

热门文章

  1. java ecdh算法_椭圆曲线ECC ECDH原理 javacard实现
  2. 即插即用 | S-FPN全新的金字塔网络,更适合轻量化模型的FPN
  3. 3D Object Detection——BEV-based methods
  4. gradle build running很慢
  5. RemoveError: 'setuptools' is a dependency of conda and cannot be removed from
  6. keras module 'tensorflow' has no attribute 'placeholder'
  7. “load”: 不是“torch::jit”的成员
  8. asyncio 并发测试
  9. Cross Entropy梯度分布拉平
  10. numpy的random模块