arrays - 【求一些提示】将排序后的数组插入到构造的BST中
问题描述
我有一个作业问题要提出一个有效的算法,将具有 m 个元素的排序数组插入到具有 n 个元素的(n 个不平衡)二叉搜索树中,这样总运行时间是 O(m+n) 而不是 m*O (n)。由于我苦苦挣扎了很长时间,但仍然没有明确的解决问题的方向,我写这篇文章是想问是否可以给出可能的提示。
解决方案
您可以使用以下算法:
对 BST 中的节点进行中序遍历,并保留对在此遍历中访问的前一个节点的引用。这个前一个节点以空值开始。保持以下不变量:要么当前节点没有左孩子,然后前一个节点为空或祖先,要么当前节点有左孩子,前一个节点是后代。
当排序数组中的下一个值小于当前节点时,则为该数组值插入一个新节点作为当前节点的左孩子(当它没有左孩子时)或作为前一个节点的右孩子(当当前节点有左孩子时)。使新创建的节点成为“上一个”节点。递增数组中的索引,并重复此步骤,直到排序后的数组中的下一个值不小于当前节点。
从中序遍历中获取下一对(前一个,当前)并重复步骤 2,直到中序遍历完成或所有数组值都已插入
如果仍有数组值,则将它们附加到中序遍历中找到的最后一个节点的右侧,始终向右加深...
这是 JavaScript 中的一个实现:
class Node {
constructor(val) {
this.val = val;
this.next = null;
}
add(val) {
if (val < this.val) {
if (!this.left) this.left = new Node(val);
else this.left.add(val);
} else {
if (!this.right) this.right = new Node(val);
else this.right.add(val);
}
}
* inorder() { // recursive
if (this.left) yield * this.left.inorder();
yield this;
if (this.right) yield * this.right.inorder();
}
addSorted(arr) {
let i = 0; // index in arr
let prev = null; // follows behind node
for (let node of this.inorder()) {
while (arr[i] < node.val) {
if (!node.left) prev = node.left = new Node(arr[i++]);
else prev = prev.right = new Node(arr[i++]);
if (i >= arr.length) return;
}
prev = node;
}
while (i < arr.length) {
prev = prev.right = new Node(arr[i++]);
}
}
}
// Demo
// Initialise tree and print the inorder traversal
let root = new Node(40);
for (let i of [30, 70, 20, 35, 60, 80, 5, 55]) root.add(i);
for (let node of root.inorder()) console.log(node.val);
// Apply the algorithm for adding a sorted list of values
root.addSorted([1, 2, 8, 22, 38, 39, 43, 50, 51, 59, 72, 100]);
console.log("after having added sorted array:");
for (let node of root.inorder()) console.log(node.val);
推荐阅读
- c++ - 具有多个输出的内联汇编块
- python - 我正在尝试制作康威生活游戏,但发生了一些事情
- batch-file - 调用一个变量,该变量的值是另一个变量的名称
- javascript - 如何对新数组进行分组?
- java - 具有多个字段的MongoDB查询
- python - Simpy:使用匹配时间存储 put/get
- mysql - MySQL中的递归CTE丢失日期
- node.js - $geoNear 仅在我给出 maxDistance = 100 * 1000 时给出结果;
- chronicle-map - 在 Chronicle Map 中存储的值中查看垃圾值
- bootstrap-modal - 关闭并重新显示后引导模式不显示 PDF 文档