[英]searching a binary search tree for parents efficiently
我正在尝试解决以下问题:
起初,我们有一个根为 0的 bst ,仅此而已。 不是我们添加n 个给定的数字,例如:
不是例如我们开始向树添加 n = 7 个数字:
19 3 5 25 21 -4 2
添加所有数字后,目标是按照添加顺序找到每个节点的父节点:
0 19 3 19 25 0 3
我的第一种方法是在添加节点的同时构建树并同时打印父节点:
private static TreeNode treeInsert(TreeNode root, TreeNode newNode) {
TreeNode y = null;
TreeNode x = root;
while (x != null) {
y = x;
if (newNode.key < x.key) x = x.left;
else x = x.right;
}
newNode.parent = y;
if (y == null) root = newNode;
else if (newNode.key < y.key) y.left = newNode;
else y.right = newNode;
return newNode;
}
还有这个辅助 class:
class TreeNode {
TreeNode left;
TreeNode right;
TreeNode parent;
int key;
public TreeNode(int key) {
this.key = key;
}
所以我可以找到父母。这里的问题是这个算法很慢。 如果给定的数字太多并且我们认为树是不平衡的,那么添加新节点可能需要很长时间。 这个问题的时间限制是1 ,由于我提到的原因,我超过了这个限制。 我无法平衡树,因为父母变了。 但也许有一种方法可以解决问题,而无需构建 bst,而只需专注于使用数字找到父母。
谢谢你。
我们可以逐段表示现有的二叉搜索树。
比方说,我们已经添加了:
0, 21, 10, -4
所以,基本上,我们有那些段[-4 0][0 10][10 21]
当我们添加一个新的数字x
时,我们只需要找到这个数字如果下降到的段是什么。 假设x = 3
所以,段是[0 10]
=> 我们把它分成[0 3][3 10]
接下来是确定这个节点的父节点是什么。 很简单,只需要跟踪稍后在段中添加的节点。 在这种情况下,肯定会在 0 之后添加 10,因此 10 应该是父级。
比方说
class Segment{
int start, end, later;
}
因此,对于上述序列,我们有段列表:
Segment (-4, 0, -4), Segment(0, 10, 10) , Segment (10, 21, 10)
如果 x = 11,它属于Segment (10, 21, 10)
,那么父节点也将是10
。
添加11
后,我们将获得段列表:
Segment (-4, 0, -4), Segment(0, 10, 10), Segment (10, 11 , 11) , Segment (11, 21, 11)
如果数字不在任何段内,这种情况也应该很简单。 我将把这个案例留给读者来解决。
维护一个平衡的 BST 来存储段列表,我们可以获得 O(n log n) 的解决方案。
你是对的,构建树可能很慢。 如果树变得退化(即它有很长的深链),那么构建树将花费O ( n ²)。 这是一个O ( n log n ) 方法。
考虑插入 19 和 3 后的树:
0
\
\
19
/
3
我们可以预测要插入的以下值的父级x :
让我们直观地写成
values 0 3 19
parents (0) (3) (3) (19)
当我们插入 5 时,我们查找它,打印它的父项(即 3)并更新我们的数据:
values 0 3 5 19
parents (0) (3) (5) (5) (19)
发生了什么变化?
您可以将顶线视为键,将底线视为值/有效负载。 所以基本上你需要一个允许O (log n ) 插入和查找的结构。 我个人喜欢这项工作的跳过列表,但任何形式的平衡树也可以。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.