本文最后更新于 2024-03-23T16:23:55+00:00
思考:既然有了高效的散列表,那使用二叉树的地方是不是都可以替换成散列表呢?有没有哪些地方是散列表做不了,必须要用二叉树来做的呢?
主要内容
二叉查找(搜索)树
定义:树中的任意节点,其左子树每个节点的值要小于该节点,而右子树每个节点的值要大于该节点
特性:支持动态数据的快速查找、插入、删除操作
查找操作
查找逻辑:查找值与根节点,若等于则返回,若小于则在左子树中递归找,否则在右子树中递归找
1 2 3 4 5 6 7 8 9 10 11
| function searchTree(root, targetValue) { let p = root
while(p) { if(targetValue > p.value) p = p.right else if(targetValue < p.value) p = p.left else return p }
return null }
|
时间复杂度:最好 O(1),最坏 O(n),平均 O(logn)
插入操作
新插入的数据一般都是在叶子节点上,所以从根节点开始比较,找到插入位置。
如果插入数据比节点大,若节点的右子树为空则插入,否则再递归遍历右子树,继续找:【如果插入数据比节点大,若节点的右子树为空则插入】
如果插入数据比节点小,若节点的左子树为空则插入,否则再递归遍历左子树,继续找:【如果插入数据比节点小,若节点的左子树为空则插入,否则再递归遍历左子树】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| function insertTree(root, targetValue) { let p = root
while(p) { if(targetValue > p.value) { if(p.right === null) { p.right = targetValue return } p = p.right } else if(targetValue < p.value){ if(p.left === null) { p.left = targetValue return } p = p.left } } }
|
时间复杂度:最好 O(1),最坏 O(n),平均 O(logn)
删除操作
三种情况:
1、若删除的节点,无子节点,则直接将父节点的指针改为 null,完成删除;比如下图删除 55
2、若删除的节点,有一个子节点(左或右),则直接将父节点的指针指向子节点,完成删除;比如下图删除 13
3、若删除的节点,有两个子节点,则先在右子树中找到最小的值,然后和该节点互换,之后再按照【1、2】情况删除该节点;比如下图删除 18
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| function deleteTree(root, tragetValue) { let p = root let pp = null
while(p) { if(targetValue === p.value) { return p } else { pp = p if(targetValue > p.value) p = p.right else p = p.left } }
if(p.right && p.left) { let minp = p.right let minpp = null while(minp.left) { minpp = minp minp = minp.left }
p.data = minp.data p = minp pp = minpp }
let child
if(p.right) child = p.right else if(p.left) child = p.left else child = null
if(pp === null) p = child else if(pp.left === p) pp.left = child else pp.right = child }
|
时间复杂度:最好 O(1),最坏 O(n),平均 O(logn)
解答思考
思考:既然有了高效的散列表,那使用二叉树的地方是不是都可以替换成散列表呢?有没有哪些地方是散列表做不了,必须要用二叉树来做的呢?
内容总结
二叉查找树:结构为 左子节点 < 节点 < 右子节点
其操作的时间复杂度跟树高度成正比,最坏为 O(n),平均为 O(logn)
新的思考
求一棵给定二叉树的高度?
根节点高度 = 根节点到叶子节点的最大边数
高度为:4
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| function heightOfBinaryTree(root, type = "tree") { if (root === null) return 0;
let leftHeight = heightOfBinaryTree(root.left, "left"); let rightHeight = heightOfBinaryTree(root.right, "right");
const height = Math.max(leftHeight, rightHeight) + 1;
return height; }
function TreeNode(val, left = null, right = null) { this.val = val === undefined ? 0 : val; this.left = left === undefined ? null : left; this.right = right === undefined ? null : right; }
const tree = new TreeNode( 1, new TreeNode(2, new TreeNode(4), new TreeNode(5)), new TreeNode(3) ); console.log(heightOfBinaryTree(tree));
|