惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Microsoft Azure Blog
Microsoft Azure Blog
V
V2EX
博客园 - 【当耐特】
WordPress大学
WordPress大学
爱范儿
爱范儿
美团技术团队
宝玉的分享
宝玉的分享
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
小众软件
小众软件
量子位
Hugging Face - Blog
Hugging Face - Blog
B
Blog RSS Feed
Recorded Future
Recorded Future
Engineering at Meta
Engineering at Meta
雷峰网
雷峰网
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
M
MIT News - Artificial intelligence
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - 聂微东
H
Hackread – Cybersecurity News, Data Breaches, AI and More
腾讯CDC
大猫的无限游戏
大猫的无限游戏
Jina AI
Jina AI
博客园 - 叶小钗
GbyAI
GbyAI
Y
Y Combinator Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
F
Full Disclosure
G
Google Developers Blog
D
Docker
T
Tailwind CSS Blog
C
Check Point Blog
Last Week in AI
Last Week in AI
人人都是产品经理
人人都是产品经理
T
The Blog of Author Tim Ferriss
B
Blog
博客园 - 三生石上(FineUI控件)
博客园 - Franky
H
Help Net Security
MyScale Blog
MyScale Blog
U
Unit 42
D
DataBreaches.Net
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
I
InfoQ
阮一峰的网络日志
阮一峰的网络日志
The GitHub Blog
The GitHub Blog
L
LangChain Blog
有赞技术团队
有赞技术团队
Martin Fowler
Martin Fowler
Microsoft Security Blog
Microsoft Security Blog

Go Further

【教程】manim动画制作工具 【直观算法】二叉树遍历算法总结 【直观算法】Egg Puzzle 鸡蛋难题 博客文章总目录 TensorSpace 一个3D神经网络可视化框架 【直观详解】通俗易懂了解什么是黎曼猜想 支持币与去中心化商业模式 那些值得一看的TED演讲附全文文稿笔记 【区块链】共识算法与如何解决拜占庭将军问题 【直观详解】让你永远忘不了的傅里叶变换解析 【直观详解】泰勒级数 微信跳一跳解题报告 Dota2-A帐效果 深入浅出看懂AlphaGo Zero/AlphaGo元 【直观详解】线性代数中的转置正交正规正定 程序员技能图谱 【直观详解】线性代数的本质 【直观详解】什么是PCA、SVD 【直观详解】什么是正则化 Pandas-Wiki 【区块链】比特币与金融、ICO和监管 【区块链】现代区块链与新技术 【区块链】一文看懂区块链:一步一步发明比特币 【直观详解】拉格朗日乘法和KKT条件 【直观详解】支持向量机SVM Dota2伤害类型详解 【直观详解】机器学习分类器性能指标详解 【直观详解】信息熵、交叉熵和相对熵 Dota2机制总结 【直观详解】Logistic Regression Xpath-Wiki PDF复制粘贴去除多余的回车符 LeetcodeNote 幕布-全平台笔记思维导图工具 深入浅出看懂AlphaGo如何下棋 【摘抄】清欢 - 林清玄 English-abbreviation 【原创】有关中国诗的那些事
【直观算法】二叉搜索树算法总结
2018-10-28 · via Go Further

【直观算法】二叉搜索树算法总结

【阅读时间】
【阅读内容】结合Leetcode相关算法题总结二叉搜索树的相关算法,包括基本的二叉搜索构建和应用,附带一些关于AVL树,红黑树的基本概念梳理

是什么

二叉搜索树(Binary Search Tree)BST是大名鼎鼎的搜索算法。在算法界,$O(n)$ 到 $O(\log_2 n)$ 的效率优化大多和BST有关

用白话文来说,二叉搜索树是一颗对于所有节点左孩子 < 根右子树 > 根的二叉树

基本操作

构建

相关例题:108. Convert Sorted Array to Binary Search Tree

已经给出了定义,Leetcode中有一道将升序数组转换成平衡二叉搜索树的题目。根据二叉树遍历一节的内容,中序遍历的顺序是左 ➜ 根 ➜ 右,再结合二叉搜索树的定义。观察知,二叉搜索树的中序遍历就是一个升序数组。那么问题就转换成了,哪颗平衡二叉树的中序遍历是这个升序数组

因为题目要求平衡二叉树,保证所有子树的高度一样,必须二分输入序列

假设输入序列为[-10,-3,0,5,9],根节点一定在mid = (start + end) // 2 位置,由递归思维:假设再次调用的函数的返回值是已经完成的子树,也就是说只需把[0, mid-1]代表的树作为左子树,和[mid+1, end]代表的树作为右子树即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution:
def sortedArrayToBST(self, nums):
"""
:type nums: List[int]
:rtype: TreeNode
"""
if not nums: return None

mid = len(nums) // 2
root = TreeNode(nums[mid])
root.left = self.sortedArrayToBST(nums[ : mid])
root.right = self.sortedArrayToBST(nums[mid+1 : ])

return root

查找

相关例题:700. Search in a Binary Search Tree

最常见的二叉树操作,查找一个对应节点,平均查找长度为 $\log_2(n)$ 。二叉搜索树性质,左孩子<根<右孩子,按照规律进行递归即可。省略迭代写法,只需要按照顺序进行一个节点一个节点顺下即可,非常简单

1
2
3
4
5
6
7
8
9
10
class Solution:
def searchBST(self, root, val):
"""
:type root: TreeNode
:type val: int
:rtype: TreeNode
"""
if not root or root.val == val:
return root
return self.searchBST(root.left, val) if val < root.val else self.searchBST(root.right, val)

判断

相关例题:98. Validate Binary Search Tree

【输入】给定一个树的结构【操作】判断这颗树是不是二叉搜索树【输出】True or False

① 使用中序遍历,结果是升序序列则为二叉搜索树(前面讲定义的时候已经讲解的原因)

② 去重复操作。①中在遍历过程就可做判断,不需要重新再做一次升序判断

这里实现使用迭代写法,递归写法比较简单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution(object):
def isValidBST(self, root):
"""
:type root: TreeNode
:rtype: bool
"""

if root is None: return True
stack, inorder = [], []
p_node = root
pre_node_val = float("-inf")
while stack or p_node:
while p_node:
stack.append(p_node)
p_node = p_node.left
cur_node = stack.pop()
inorder.append(cur_node.val)
if pre_node_val >= cur_node.val:
return False
pre_node_val = cur_node.val
if cur_node.right:
p_node = cur_node.right
return True

删除

二叉查找树中的删除节点操作,详见链接

需要分为3种情况进行讨论

  • 没有孩子的节点 ➜ 直接将它删除即可,它的父节点的孩子替换成空
  • 只有一个孩子的节点 ➜ 直接上升孩子的位子替代被删除的即可
  • 两个孩子的节点 ➜ 此种情况比较麻烦,需要参看详细链接

相关题目