繁体   English   中英

有效地为父母搜索二叉搜索树

[英]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

  • 如果x < 0 则其父级将为 0;
  • 如果 0 < x < 3 那么它的父级将是 3(左手孩子,但这并不重要);
  • 如果 3 < x < 19 那么它的父级将是 3(右手孩子);
  • 如果 19 < x那么它的父级将是 19。

让我们直观地写成

values         0       3                     19
parents   (0)     (3)             (3)             (19)

当我们插入 5 时,我们查找它,打印它的父项(即 3)并更新我们的数据:

values         0       3          5          19
parents   (0)     (3)       (5)        (5)        (19)

发生了什么变化?

  • 我们在其排序位置插入了 5(在 3 到 19 之间);
  • 我们在相应的父母 position 中将 3 更改为 5;
  • 我们在第一个旁边插入了另外 5 个。

您可以将顶线视为键,将底线视为值/有效负载。 所以基本上你需要一个允许O (log n ) 插入和查找的结构。 我个人喜欢这项工作的跳过列表,但任何形式的平衡树也可以。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM