第93题 求一个二叉搜索树的第k小值
二叉树
- 二叉树是一棵树
- 二叉树每个节点最多只能有两个子节点
- 树节点的数据结构
{value,left?,right?} - 二叉树的遍历
- 前序遍历:
root=>left=>right - 中序遍历:
left=>root=>right - 后序遍历:
left=>right=>root
- 前序遍历:
- 二叉搜索树
BST(Binary Search Tree)的特点left(包含其后代)value<=root valueright(包含其后代)value>=root value- 二叉搜索树的价值可以让我们使用二分法 快速查找

思路分析
- 二叉搜索树中序遍历 ,即从小到大的排序
- 找到排序后的第
k值即可
/**
* @description 二叉搜索树
*/
// 数据结构
interface ITreeNode {
value: number
left: ITreeNode | null
right: ITreeNode | null
}
const arr = []
/**
* 二叉树前序遍历
* @param node:ITreeNode tree node
*/
function preOrderTraverse(node) {
if (node == null) return
// console.log(node.value)
arr.push(node.value)
preOrderTraverse(node.left)
preOrderTraverse(node.right)
}
/**
* 二叉树中序遍历
* @param node:ITreeNode tree node
*/
function inOrderTraverse(node) {
if (node == null) return
inOrderTraverse(node.left)
// console.log(node.value)
arr.push(node.value)
inOrderTraverse(node.right)
}
/**
* 二叉树后序遍历
* @param node:ITreeNode tree node
*/
function postOrderTraverse(node) {
if (node == null) return
postOrderTraverse(node.left)
postOrderTraverse(node.right)
// console.log(node.value)
arr.push(node.value)
}
/**
* 寻找 BST 里的第 K 小值
* @param node tree node:ITreeNode
* @param k:number 第几个值
*/
function getKthValue(node, k) {
inOrderTraverse(node) // 中序遍历
// arr => [2, 3, 4, 5, 6, 7, 8]
// k - 1从0开始
return arr[k - 1] || null
}

- 前序遍历(根左右):
5324768 - 中序遍历(左根右):
2345678 - 后序遍历(左右根):
2436875
// 测试
const bst = {
value: 5,
left: {
value: 3,
left: {
value: 2,
left: null,
right: null
},
right: {
value: 4,
left: null,
right: null,
}
},
right: {
value: 7,
left: {
value: 6,
left: null,
right: null
},
right: {
value: 8,
left: null,
right: null
}
}
}
// preOrderTraverse(bst)
// inOrderTraverse(bst)
// postOrderTraverse(bst)
console.log(getKthValue(bst, 3)) // 4
拓展:为什么二叉树很重要,而不是三叉树四叉树
因为二叉树可以进行二分法快速查找
- 数组:查找快,时间复杂度
O(1),增删慢,时间复杂度O(n) - 链表:查找慢,时间复杂度
O(n),增删快,时间复杂度O(1) - 二叉搜索树BST :
查找快,增删快,可以弥补数组、链表的缺点
1.平衡二叉树
BST如果不平衡,那就成链表了- 所以要尽量平衡:平衡二叉搜索树
BBST BBST增删查,时间复杂度都是O(logn),即树的高度(n树的节点数)
2.红黑树

- 一种自平衡二叉树
- 分为红/黑两种颜色,通过颜色转化来维持树的平衡
- 相对于普通平衡二叉树,它维持平衡的效率更高
3.B树

- B树是二叉树的一个变种,目的是为了高效维持平衡,高效去计算
- 物理上是多叉树,逻辑上是二叉树
- 一般用于高效
I/O,关系型数据库(MySQL)常用B树来组织数据
4.小结
- 数组链表各有各的缺点
- 特点的二叉树(平衡二叉树BBST)可以让整体效果最优
- 各种高级二叉树,继续优化,满足不同场景
拓展:堆有什么特点,和二叉树有什么关系

- 堆是一个完全二叉树
- 最大堆:父节点 >= 子节点
- 最小堆:父节点 <= 子节点
逻辑结构vs物理结构
- 堆,逻辑结构是一颗二叉树,物理结构是一个数组
- 数组:适合连续存储 + 节省空间


堆 vs BST
- 查询比BST慢,BST规则比较严格可以使用二分
- 增删比较BST快,维持平衡更快,因为规则比较简单
- 但整体的时间复杂度都在
O(logn)级别,即树的高度(n树的节点数)
堆的使用场景
- 堆的数据都是在栈中引用的,不需要从root遍历
- 堆恰巧是数组形式,根据栈的地址,可用
O(1)找到目标
