二叉查找树或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。

二叉搜索树不一定是完全二叉树,因此不能像堆一样可以数组表示。

定义一个TNode类来实例化节点,有key,value,l_child,r_child属性。其中key,value通过构造函数传入,l_child,r_child初始化为None。

再定义一个BSTree类,根节点初始化为None。

然后给BSTree添加以下方法:

insert(key,value) 插入一个节点

update(key,value) 更新节点的值

search(key) 通过key来找相应节点的value

remove(key) 通过key来删除树中相应节点

以及深度优先和广度优先的遍历方法。

insert:

传入参数key,value,插入一个新的节点。但是如果树中已经存在key为key的节点,就将插入操作转变为更新操作。

def __insert(self, key, value, curr_node):

if curr_node is None:

return TNode(key, value)

if key < curr_node.key:

curr_node.l_child = self.__insert(key, value, curr_node.l_child)

elif key > curr_node.key:

curr_node.r_child = self.__insert(key, value, curr_node.r_child)

else:

curr_node.value = value

return curr_node

当当前的节点为None时,根据参数中的key和value建立新的节点,并返回这个节点。当key值小于当前节点的key时,将新节点插入到当前节点的左子树的相应位置,然后返回当前节点。同理key值大于当前节点的key时,将新节点插入到当前节点的右子树的相应位置,返回当前节点。如果key等于当前节点key,将插入操作改变为更新操作。

search:

def __search(self, node, key):

if node:

if node.key == key:

return node

elif node.key > key:

return self.__search(node.l_child, key)

else:

return self.__search(node.r_child, key)

return False

在当前node为根节点的子树中,查找key为key的子节点,如果当前node的key值与参数相同,返回当前节点。否则递归地到左右子树中找key为key的节点,如果没有找到,最终返回False。

update:

def __update(self, key, value, node):

if node:

if node.key == key:

node.value = value

elif node.key > key:

self.__update(key, value, node.l_child)

else:

self.__update(key, value, node.r_child)

在当前node为根节点的子树中,查找key为key的节点。如果当前node的key值与参数相同,更新当前节点的value。否则递归地到左右子树中找到key为key的节点,并更新value。

remove:

执行remove操作时,分为两种情况。

1.当前要删除的节点没有右子节点,此时将左子节点作为当前节点,返回。

2.当前要删除的节点(node_to_delete)有右子节点(r_child),找到右子节点下,最小的节点(r_child_smallest_child),将该节点与要删除的节点换位置。具体操作为:先拿到r_child_smallest_child,再将该节点从以r_child为根的子树中删除。再将node_to_delete的左孩子作为r_child_smallest_child的左孩子,node_to_delete的右孩子作为r_child_smallest_child的右孩子。最终将r_child_smallest_child赋给node_to_delete,并返回。

代码如下:

def __remove(self, node, key):

if node:

if node.key < key:

node.r_child = self.__remove(node.r_child, key)

elif node.key > key:

node.l_child = self.__remove(node.l_child, key)

else:

if node.r_child is None:

node = node.l_child

else:

node_r_child_smallest_child = self.__get_smallest_child(node.r_child)

self.__remove_smallest(node.r_child)

node_r_child_smallest_child.r_child = node.r_child

node_r_child_smallest_child.l_child = node.l_child

node = node_r_child_smallest_child

return node

return False

其中__remove_smallest和__get_smallest_child含义分别是:删除当前节点下,最小的节点,以及获得当前节点下最小的节点。

代码如下:

def __remove_smallest(self, node):

if node.l_child:

node.l_child = self.__remove_smallest(node.l_child)

return node

return node.r_child

当当前节点有左孩子时,删除左子树中最小的节点,并且返回当前节点。没有左孩子时,返回右孩子。

def __get_smallest_child(self, node):

if node.l_child:

return self.__get_smallest_child(node.l_child)

return node

当当前节点有左孩子时,获得左子树中最小的节点。没有左孩子时,返回当前节点。

深度优先遍历,可以选择先序遍历,中序遍历,后续遍历,以其中之一为例:

def __l_m_r(self, node):

if node:

self.__l_m_r(node.l_child)

print(node)

self.__l_m_r(node.r_child)

当进行广度优先遍历时,需要用到队列。

def bfs(self):

queue = deque()

queue.append(self.root)

while queue:

node = queue.popleft()

if node:

l_child = node.l_child

r_child = node.r_child

print(node.value)

queue.append(l_child)

queue.append(r_child)

以上是我所了解的二叉搜索树的基本功能

用python实现搜索树_二叉搜索树的python实现相关推荐

  1. 中根遍历二叉查找树所得序列一定是有序序列_二叉搜索树(BST)

    点击上方"蓝字",发现更多精彩. 前面我们介绍了树的基本概念,并引出了二叉树.值得注意的是,无特征的二叉树在工程上几乎没啥用处,一般都是使用bst.avl,trie,rbtree等 ...

  2. 2.13_binary_search_tree(BST)_二叉搜索树

    二叉树节点类 class BiTreeNode(object):"""二叉树节点类"""def __init__(self, data):s ...

  3. Python 数据结构与算法——二叉搜索树的实现

    class Tree:本身自然需要维护根节点(root),用于指向树的第一个节点 class Tree:root = None class Node:每一个节点都要维护左子树.右子树 class No ...

  4. 173. 二叉搜索树迭代器(二叉搜索树+栈)

    实现一个二叉搜索树迭代器.你将使用二叉搜索树的根节点初始化迭代器. 调用 next() 将返回二叉搜索树中的下一个最小的数. 示例: BSTIterator iterator = new BSTIte ...

  5. HDU3791 二叉搜索树【二叉搜索树】

    二叉搜索树 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submiss ...

  6. pta 是否完全二叉搜索树_23.二叉搜索树的后序遍历序列

    点击上方蓝字,关注并星标,和我一起学技术. 题目描述 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则返回true,否则返回false.假设输入的数组的任意两个数字都互不相同. ...

  7. python最大堆_二叉堆 及 大根堆的python实现

    Python 二叉堆(binary heap) 二叉堆是一种特殊的堆,二叉堆是完全二叉树或者是近似完全二叉树.二叉堆满足堆特性:父节点的键值总是保持固定的序关系于任何一个子节点的键值,且每个节点的左子 ...

  8. python生成器迭代_二十、深入Python迭代器和生成器

    「@Author:Runsen」 学习python的过程中,迭代器与生成器是绕不开的话题, 什么是迭代器和生成器呢? 下面我们来了解一下什么是迭代.但在了解迭代器之前,首先需要知道什么是容器. 容器 ...

  9. python 累加直方图_二维数组的Python累积直方图

    我现在是matplotlib(http://matplotlib.sourceforge.net/)的超级粉丝.它有许多内置的功能,几乎每一种类型的绘图你想做.在 下面是一大堆关于如何创建直方图的示例 ...

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

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

最新文章

  1. 图灵赠书——程序员12月书讯
  2. boost::ratio_greater相关的测试程序
  3. 【Qt】2D绘图之绘制文字
  4. 平安性格测试题及答案_面试要求做性格测试,该怎么做?
  5. python画彩虹爱心_用python画一颗彩虹色爱心送给女朋友!!!
  6. linux下的微博客户端,Linux下非官方的新浪微博客户端:WeCase(微盒),附安装方法...
  7. python怎么发音乐到朋友圈_只要三步,用Python轻松制作短视频,你也能在朋友圈傲娇一把!...
  8. android markdown 框架,Android Studio MarkDown风格README的正确打开姿势
  9. 【c语言】调整数组使奇数所有都位于偶数前面
  10. 2019-05-16mysql忘记密码怎么办
  11. meaven插件通过绑定生命周期_容器镜像服务联手 IDE 插件,实现一键部署、持续集成与交付...
  12. mysql 备份任务_设置mysql 定时备份任务
  13. elk日志管理系统搭建
  14. Photoshop 更改图片颜色
  15. 曲苑杂坛--DML操作中如何处理那些未提交的数据
  16. dell服务器bios修改uefi,Dell PowerEdge BIOS 和 UEFI 参考指南
  17. 广域网(WAN)简介
  18. 51单片机8位带符号乘法运算(汇编)
  19. gtsam 学习十(ISAM2 理论)
  20. EF更新使用AutoMapper_se7en3_新浪博客

热门文章

  1. 反驳《SEO的几大罪行》
  2. order by 多个条件
  3. Xshell连接VMware虚拟机(CentOs7)
  4. idea面板右下角的切换分支找不到
  5. Elastic 技术栈之 Logstash 基础
  6. Skyline Web 二次开发- 1.地图显示、Position、AttachEvent
  7. 使用 Google Guava 美化你的 Java 代码
  8. 625某电商网站数据库宕机故障解决实录(上)
  9. xcode自动刷新resource下的文件
  10. greenplum管理员日常任务