簡體   English   中英

二叉搜索樹中序遍歷算法的時間分析

[英]Time analysis of a Binary Search Tree in-order traversal algorithm

下面是一個迭代算法,在不使用 Stack 的情況下以有序的方式遍歷二叉搜索樹(首先是left child ,然后是parent ,最后是right child ):

(想法:整個想法是找到樹的最左邊的子節點,並每次找到手頭節點的后繼節點並打印其 value ,直到沒有更多節點剩余。)

void In-Order-Traverse(Node root){
     Min-Tree(root); //finding left-most child
     Node current = root;
  while (current != null){
     print-on-screen(current.key);
     current = Successor(current);
  }
  return;
}

Node Min-Tree(Node root){ // find the leftmost child
   Node current = root;
   while (current.leftChild != null)
      current = current.leftChild;
   return current;
}

Node Successor(Node root){
  if (root.rightChild != null) // if root has a right child ,find the leftmost child of the right sub-tree
    return Min-Tree(root.rightChild);
  else{
    current = root;
    while (current.parent != null && current.parent.leftChild != current)
        current = current.parent;
    return current.parrent;
  }
}

有人聲稱該算法的時間復雜度是Theta(n)假設 BST 中有n節點,這肯定是正確的。 但是我無法說服自己,因為我猜有些節點被遍歷的次數超過了恆定次數,這取決於其子樹中的節點數,並且總結所有這些訪問次數不會導致Theta(n)

關於如何證明它的任何想法或直覺?

邊緣而不是節點更容易推理。 讓我們根據Successor函數的代碼進行推理。

情況1( then分支)

對於所有帶有右子節點的節點,我們將訪問一次右子樹(“右轉”邊緣),然后始終使用Min-Tree功能訪問左子樹(“左轉”邊緣)。 我們可以證明這種遍歷將創建一條路徑,該路徑的邊沿是唯一的-在具有正確子級的任何其他節點進行的遍歷中,這些邊線都不會重復,因為這種遍歷可確保您永遠不會訪問任何“右轉”邊沿樹上的其他節點。 (通過構造證明)。

情況2( else分支)

對於所有沒有右子節點的節點( else分支),我們將通過遵循“右轉”邊來訪問祖先,直到您必須做出“左轉”邊或遇到二叉樹的根為止。 同樣,生成的路徑中的邊是唯一的-在沒有合適的子節點的情況下,從任何其他節點進行的任何其他遍歷都不會重復。 這是因為:

  • 除了起始節點和通過“左轉”邊沿到達的節點之外,其他所有節點之間都有一個右子節點(這意味着這些節點將從else分支中排除)。 當然,起始節點沒有合適的孩子。
  • 每個節點都有一個唯一的父節點(只有根節點沒有父節點),並且到父節點的路徑是“左轉”或“右轉”(該節點是左子節點還是右子節點)。 給定任何節點(忽略右子條件),只有一條路徑可以創建模式:許多“右轉”然后是“左轉”。
  • 由於中間的節點有一個正確的子節點,因此無法從不同的節點開始以2次遍歷出現邊。 (因為我們當前正在考慮沒有合適孩子的節點)。

(這里的證明是揮舞自己的手,但是我認為可以通過矛盾來正式證明)。

由於邊是唯一的,因此僅在情況1(或僅情況2)下遍歷的邊的總數為O(n)(因為樹中的邊數等於頂點數-1)。 因此,將這兩種情況相加后,有序遍歷將為O(n)。

請注意,我只知道每個邊最多訪問一次-我不知道是否從證明中訪問了所有邊,但是邊的數量由頂點數限制,這是正確的。

我們可以很容易地看到它也是Omega(n)(每個節點都被訪問過一次),因此我們可以得出結論,它也是Theta(n)。

給定的程序以Θ(N)時間運行。 Θ(N)並不意味着每個節點都被精確地訪問過一次。 請記住,有一個常數。 因此,Θ(N)實際上可能受到5 N10 N甚至1000 N的限制 因此,它無法為您提供訪問節點的次數的准確計數。

二進制搜索樹的有序迭代遍歷的時間復雜度可以分析如下:

考慮一個具有N個節點的樹,

假設執行時間由復雜度函數T(N)

令左子樹和右子樹分別包含X和NX-1節點,

然后,時間復雜度T(N) = T(X) + T(NX-1) + c

現在考慮一下BST的兩種極端情況,

情況1:一個BST完全平衡,即兩個子樹的節點數相等。 例如,考慮以下所示的BST,

                        10
                       /  \
                      5   14
                     / \  / \
                    1  6 11 16 

對於這樣的樹,復雜度函數是

T(N) = 2 T(⌊N/2⌋) + c

母定理在這種情況下給了我們Θ(N)的復雜度。

情況2:完全不平衡的BST,即左子樹或右子樹為空。 對於X =0。例如,考慮以下所示的BST

               10
              /
             9
            /
           8
          /
         7    

現在T(N) = T(0) + T(N-1) + c

T(N) = T(N-1) + c
T(N) = T(N-2) + c + c
T(N) = T(N-3) + c + c + c
 .
 .
 .
T(N) = T(0) + N c

由於T(N)= K,其中K為常數,

T(N)= K + N c

T(N)=Θ(N)。

因此,對於所有情況,復雜度均為Θ(N)

我也無法想象這將是O(n)。 僅查找有序后繼者,即Node Successor(Node root)為O(log n),因為它取決於樹的高度。 對n個節點中的每個節點執行此操作將產生O(n log n)。

我們專注於邊緣而不是節點。 (為了更直觀地看這張圖片: http : //i.stack.imgur.com/WlK5O.png

我們聲稱,在該算法中,每個邊緣最多被訪問兩次(實際上它被訪問了兩次)。

第一次向下遍歷,第二次向上遍歷。 要訪問邊緣兩次以上,我們必須再次遍歷該邊緣:向下,向上, 向下 ,...。

我們證明不可能再次進行邊緣向下訪問。

讓我們假設我們遍歷edge (u , v)向下第二次,這意味着祖先之一u有一個繼任者是一個繼承人u

這是不可能的 :

我們知道,當我們向上穿越一條邊時,我們正在尋找左轉邊緣以找到后繼者,因此,當u在后繼者的左側時,此后繼者的后繼者在其右側,通過移到后繼者的右側(以找到其后繼者)再次到達u ,因此再次無法獲得edge (u,v) (要找到繼任者,我們可以向右或向上移動,但不能向左移動)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM