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