一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第9天,点击查看活动详情。
如何找到二叉搜索树中第k小值呢?要想解决这个问题,首先需要了解什么是二叉树?
二叉树
1、特点
- 它是一种树形结构
- 每个节点最多有两个节点
- 树节点的数据结构{value,left?,right?},?表示可有可无。
2、图例
3、二叉树的遍历
- 前序遍历:root -> left -> right
相对上图得到的就是:A -> B -> C - 中序遍历:left -> root -> right
相对上图得到的就是:B -> A -> C - 后序遍历:left -> right -> root
相对上图得到的就是:A -> C -> B
4、代码演示
根据上方图片编写相对应的二叉树结构的js代码,并进行遍历
- 定义二叉树中节点类型
interface TreeNode {
value: number,
left: TreeNode | null,
right: TreeNode | null
}
- 二叉树结构代码
const binarySearchTree: TreeNode = {
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
},
}
}
- 前序遍历
function preOrderTravers(binarySearchTree: TreeNode | null){
if(binarySearchTree == null) return
console.log(binarySearchTree.value)
preOrderTravers(binarySearchTree.left)
preOrderTravers(binarySearchTree.right)
}
preOrderTravers(binarySearchTree)//5、3、2、4、7、6、8
- 中序遍历
function inOrderTravers(binarySearchTree: TreeNode | null){
if(binarySearchTree == null) return
inOrderTravers(binarySearchTree.left)
console.log(binarySearchTree.value)
inOrderTravers(binarySearchTree.right)
}
inOrderTravers(binarySearchTree)//2、3、4、5、6、7、8
- 后序遍历
function postOrderTravers(binarySearchTree: TreeNode | null){
if(binarySearchTree == null) return
postOrderTravers(binarySearchTree.left)
postOrderTravers(binarySearchTree.right)
console.log(binarySearchTree.value)
}
postOrderTravers(binarySearchTree)//2、4、3、6、8、7、5
从上方的代码,结合上方的图形,可以帮助我们更好的理解二叉树的遍历。
二叉搜索树
1、特点
在二叉树的特点上增加
- left(包括其子节点)的value值 一定 不大于 root的value
- right(包括其子节点)的value值 一定 不小于 root的value 目的:可以使用二分查找快速查找某个值
2、图例
解题
1、思路
- 在二叉搜索树中使用中序遍历,就可以将value的值按照从小到大的顺序进行排列
- 排序后第k个值就是我们需要的值
2、代码
//改变中序遍历
const binarySearchTreeArr: number[] = [];
function inOrderTraversNew(binarySearchTree: TreeNode | null){
if(binarySearchTree == null) return
inOrderTraversNew(binarySearchTree.left)
binarySearchTreeArr.push(binarySearchTree.value)
inOrderTraversNew(binarySearchTree.right)
}
function getKValue(binarySearchTree: TreeNode, k:number): number | null{
inOrderTraversNew(binarySearchTree)
return binarySearchTreeArr[k - 1] || null
}
//功能测试
console.log(binarySearchTree,3)//4
功能测试符合预期
3、复杂度分析
空间复杂度是O(n),随着二叉搜索树结构的数据的增大,内存等比例增大,所以空间复杂度是O(n);
时间复杂度是0(logn),采用了二分的思想,虽然催在递归操作,但时间复杂度依然是0(logn);
延展
数组,链表,二叉树的复杂度分析
- 数组操作的时间复杂度可能是O(n):push,也可能是O(1):pop
- 链表操作的时间复杂度可能是O(n):查找,也可能是O(1):增加、删除
- 二叉树:
- 如果其每个节点都只有一个分支,即只有left或者只有right,那么它就变成了链表
- 其操作效率最高的结构是一种平衡结构BBST(balance binary search tree):平衡二叉查找树,这种状态下的操作时间复杂度都是O(logn)