上图:

这是二叉搜索树(也有说是查找树的)基本结构:如果y是x的左子树中的一个结点,那么y.key <= x.key(如a图中的6根结点大于它左子树的每一个结点 6 >= {2,5,5}),如果y是x的右子树中的一个结点,那么y.key >x.key

注:不同堆,堆是中间的结点最大或最小,而二叉搜索树是左中右的大小顺序,我们用这个特性来遍历二叉搜索树得到是他的顺序排列(中序遍历)#中在什么地方就叫什么遍历 如前序遍历:中左右  后序:左右中

如图a他的中序遍历为 2->5->5->6->7->8 #从大到小

基本操作:

SEARCH:查找关键字为k的结点  O(h) #h为二叉树的高度

MINIMUM:查找二叉树的最小值(显然是最左的那个结点) O(h)

MAXIMUM:查找二叉树的最大值(显然是最右的那个结点) O(h)

PREDECESSOR:查找x的前驱y O(h)

SUCCESSOR:查找x的后驱y O(h)

INSERT:插入结点z O(h)

DELETE:删除结点z O(h)

注:

1.其中插入和删除因为要调整树的结构所以有点复杂

2.复杂都为O(h) #h为二叉树的高度,我们看下图

他们的结点数(n)都是6但是高度是不同的 ha = 2 而 hb = 4 ,这种差距在应用中可能会有很大的性能问题,同以前的快速排序一样使用随机化方法或者是其他的限定条件(如红黑树)来保证性能在一个好一点的范围内(h = logn),就是不能让二叉树保持一条直线向下

给出python实现:

 class Node: #结点

     def __init__(self,data):
self.left = None
self.right = None
self.parent = None
self.data = data
def createNode(self,data):
#初始化
return Node(data) def inorder_tree_walk(self):
"""
中序遍历
"""
if self.left: #左
self.left.inorder_tree_walk()
print(self.data,end = ' ') #中
if self.right: #右
self.right.inorder_tree_walk()
def tree_search(self,data):
if self == None or self.data == data:
return self if data < self.data:
return self.left.tree_seatch(data)
else :
return self.right.tree_seatch(data) def iterative_tree_search(self,data):
#非递归版查找一般会比递归版更快
n = self
while n != None and data != n.data:
if data < n.data:
n = n.left
else:
n = n.right
return n def tree_mininum(self):
if self.left:
return self.left.tree_mininum()
else:
return self def tree_maximun(self):
if self.right:
return self.right.true_maximun()
else:
return self def tree_successor(self): """
找后继:
有右子树,取右子树中最小的
没有右子树,也就是这个子树中最大的,应该向上找第一个把他当右子树的结点
前驱 相反
"""
x = self
if x.right != None:
return x.right.tree_mininum()
else:
p = x.parent
while p and p.right == x:
x = p
p = p.parent
return p
def tree_predecessor(self):
x = self
if x.left != None:
return x.left.tree_maximun()
else:
p = x.parent
while p and p.left == x:
x = p
p = p.parent
return p def tree_insert(self,data):
#插入data
node = self
while node:
if data < node.data:
next = node.left
else:
next = node.right
if next:
node = next
else:
break
nn = self.createNode(data)
if data < node.data:
node.left = nn
node.left.parent = node
else:
node.right = nn
node.right.parent = node
return nn def tree_delete(self,root):
'''
1.有2子树
1.相对树结构移除的是self 2.少于有2子树
1.相对树结点移除的是self的后继 当然删除还是self.data
''' n = self if n.left == None or n.right == None :
y = n #至多有1子树直接删除
else:
y = n.tree_successor()#要用后继覆盖他 if y.left == None: #x 覆盖 y #至多有1个子树 y是黑的话 x的黑+1
x = y.right
else:
x = y.left x.parent = y.parent
if y.parent == None:
root = x
elif y == y.parent.left:
y.parent.left = x
else:
y.parent.right = x if y != n:
n.data = y.data
return root; if __name__ == '__main__':
root = Node(6)
root.tree_insert(5)
root.tree_insert(7)
root.tree_insert(2)
root.tree_insert(3)
root.tree_insert(8)
print("中序遍历: ",end = '')
root.inorder_tree_walk()
print("\n查找:",end = '')
test1= root.iterative_tree_search(5)
print(str(test1.data)+'的后继:'+str(test1.tree_successor().data)) print("查找:",end = '')
test2= root.tree_search(6)
print(str(test2.data)+'的前驱:'+str(test2.tree_predecessor().data))
root = test2.tree_delete(root)
print("删除6后:",end = '')
root.inorder_tree_walk()
root = root.iterative_tree_search(2).tree_delete(root)
print("\n删除2后:",end = '')
root.inorder_tree_walk()
'''
================= RESTART: F:\python\algorithms\12_1_tree.py =================
中序遍历: 2 3 5 6 7 8
查找:5的后继:6
查找:6的前驱:5
删除6后:2 3 5 7 8
删除2后:3 5 7 8
>>> python 3.5.1 win7
'''

参考引用:

http://www.wutianqi.com/?cat=515&paged=4

http://blog.csdn.net/fxjtoday/article/details/6448083

算法导论 第十二章 二叉搜索树(python)的更多相关文章

  1. 算法导论(Introduction to Algorithms )— 第十二章 二叉搜索树— 12.1 什么是二叉搜索树

    搜索树数据结构支持很多动态集合操作,如search(查找).minmum(最小元素).maxmum(最大元素).predecessor(前驱).successor(后继).insert(插入).del ...

  2. 算法导论第十八章 B树

    一.高级数据结构 本章以后到第21章(并查集)隶属于高级数据结构的内容.前面还留了两章:贪心算法和摊还分析,打算后面再来补充.之前的章节讨论的支持动态数据集上的操作,如查找.插入.删除等都是基于简单的 ...

  3. 【Coding算法导论】第4章:最大子数组问题

    Coding算法导论 本系列文章主要针对算法导论一书上的算法,将书中的伪代码用C++实现 代码未经过大量数据测试,如有问题,希望能在回复中指出! (一)问题描述 给定一个数组,求数组中连续的子数组的和 ...

  4. 小白专场-是否同一颗二叉搜索树-python语言实现

    目录 一.二叉搜索树的相同判断 二.问题引入 三.举例分析 四.方法探讨 4.1 中序遍历 4.2 层序遍历 4.3 先序遍历 4.4 后序遍历 五.总结 六.代码实现 一.二叉搜索树的相同判断 二叉 ...

  5. Leetcode 98 验证二叉搜索树 Python实现

    给定一个二叉树,判断其是否是一个有效的二叉搜索树. 假设一个二叉搜索树具有如下特征: 节点的左子树只包含小于当前节点的数. 节点的右子树只包含大于当前节点的数. 所有左子树和右子树自身必须也是二叉搜索 ...

  6. LeetCode 98. 验证二叉搜索树 | Python

    98. 验证二叉搜索树 题目来源:https://leetcode-cn.com/problems/validate-binary-search-tree 题目 给定一个二叉树,判断其是否是一个有效的 ...

  7. 【原创】《算法导论》链表一章带星习题试解——附C语言实现

    原题: 双向链表中,需要三个基本数据,一个携带具体数据,一个携带指向上一环节的prev指针,一个携带指向下一环节的next指针.请改写双向链表,仅用一个指针np实现双向链表的功能.定义np为next ...

  8. 二叉搜索树(python)

    # -*- coding: utf-8 -*- class BSTNode(object): def __init__(self, key, value, left=None, right=None) ...

  9. LeetCode--096--不同的二叉搜索树(python)

    我的思路比较low直接看官方题解吧... class Solution: def numTrees(self, n: int) -> int: G = [0] * (n+1) G[0],G[1] ...

随机推荐

  1. 用eclipse-inst-win64.exe安装eclipse出现Java for Windows Missing 的原因

    Java for Windows Missing 因为jdk的版本没有对,我这里是64位的机器上安了32位的jdk,所以一直报这个. 必须换上相对应版本的jdk,提示页面有链接,直接点击就可以下载. ...

  2. 164 Maximum Gap 最大间距

    给定一个无序的数组,找出数组在排序后相邻的元素之间最大的差值.尽量尝试在线性时间和空间复杂度情况下解决此问题.若数组元素个数少于2,则返回0.假定所有的元素都是非负整数且范围在32位有符号整数范围内. ...

  3. 动手实现 Redux(一):优雅地修改共享状态

    从这节起我们开始学习 Redux,一种新型的前端“架构模式”.经常和 React.js 一并提出,你要用 React.js 基本都要伴随着 Redux 和 React.js 结合的库 React-re ...

  4. P1847 轰炸II

    题目背景 本题为轰炸数据加强版 题目描述 一个城市遭到了M次轰炸,每次都炸了一个每条边都与边界平行的矩形 在轰炸后,有N个关键点,指挥官想知道,它们有没有受到过轰炸,如果有,被炸了几次,最后一次是第几 ...

  5. hihocoder1079 离散化

    思路:线段树 + 离散化. 测试用例: 3 10 1 10 1 3 6 10 实现: #include <bits/stdc++.h> using namespace std; typed ...

  6. 微信小程序 开放能力学习

    1. 用户信息小程序登录使用微信的个人信息快速搭建用户体系,登录逻辑:小程序向微信获取code 给服务端生成用户. 说明1. 小程序端调用 wx.login() 获取临时登录凭证 code,并传到服务 ...

  7. struct和union

    struct的小秘密 C语言中的struct可以看做变量的集合,struct的问题: 空结构体占用多大内存? 例子1:空结构体的大小 #include<stdio.h> struct ST ...

  8. 正则表达式中的?=,?!,?<=,?<!(预查)解释小栗子

    之前在学正则表达式的时候学的并不是很透彻 感觉看看元字符(元字符要用 \ 转义),限定符(^开头 $结尾),   前面写个范围[a-z],在后面写个{n,}能匹配就行了 当时的自己 然而昨天我参加了个 ...

  9. iframe 完全跨域自适应高度

    1.跨域访问页面, 需要访问后台的页面,通过后台调转 2.跨域自适应宽高   思路:通过相互嵌套,获取跨域页面的高度,通过src传回到本域,通过parent方法设置主页的iframe的高度 index ...

  10. Hello Shell

    shell是Linux平台的瑞士军刀,能够自动化完成很多工作.要了解UNIX 系统中可用的 Shell,可以使用 cat /etc/shells 命令.使用 chsh 命令 更改为所列出的任何 She ...