簡體   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