2017-02-23 85 views
4

我最近遇到以下問題據說已經在技術面試被問出來的葉節點:給定一個二叉搜索樹,怎樣的序遍歷如何識別二叉搜索樹

我們是否在沒有構建樹的情況下識別葉節點?

例如:[5,3,2,4,8,7,9]

問題被留下的模糊誰貼吧和給出的模糊,我真的不知道有什麼辦法應該是爲這一個,我還沒有能夠找到在線驗證的解決方案。

該問題應該如何解決?

回答

5

考慮您的例子:[5,3,2,4,8,7,9]

採取的第一個元素:5

由於這是一個預先遍歷這就是根節點肯定。

現在,在序遍歷,後根ü復發的左子樹然後右子樹

和U也知道,在BST

nodes in left subtree < root < nodes in right subtree 

5後因此,所有串聯其中小於5元素屬於左子樹。同樣對於正確的。

還是你最終擁有這個(你不需要明確的創建樹)

 5 
    / \ 
    [3,2,4] [8,7,9] 

現在[3,2,4]是左子樹部分序遍歷和[8,7,9]右。

爲兩個子數組執行遞歸操作,並且當您剩下大小爲1的數組時,這就是葉子。

+0

這種方法似乎是正確的,雖然它是基於樹的完美和完整的假設,如另一個答案中所建議的。 – loremIpsum1771

+2

我不認爲這棵樹需要完美或完整。例如:對於[2,3],這不是一個完美的樹,但算法適用於它。 –

1

我假設我們只考慮perfect BST。因爲如果它不完美,可能會有(可能)多種答案。

因此,看看preorder traversal的例子和描述,很明顯,根是先採取的,然後是「下」葉。因爲我們有一棵完美的樹,所以我們可以看到葉子總是成對的。而且我們還需要「跳過」他們的父母。

憑直覺,我建議倒退,因爲去年2個元素是葉( '*' 表示沒有葉):

[*,*,2,4,*,7,9] < - 的全部測試步驟如下(倒退):

  1. 需要2片葉子;
  2. 跳過1個節點(他們的父母);
  3. 重複步驟[1-2];
  4. 跳過1個節點(父母的父母);
  5. 完成(沒有更多元素了)。

現在演示的較大陣列上(15個元素,再次完美樹):

[*,*,*,l,l,*,l,l,*,*,l,l,*,l,l] < - ,其中l表示葉。步驟(也向後):

  1. 1-4 from prevoius example;
  2. 再前面的例子1-4;
  3. 跳過1個節點(家長父母的父母);
  4. 完成(沒有更多元素)。

希望你有個想法。

至於的程序化的方法,可以發現在上面直觀的方法的重複圖案,並使用依賴於樹的高度遞歸(可easilly計算爲log2(n+1)其中n是在樹中的元素的數目,也期待wiki)但可能從數組的開始開始。僞代碼:

void getLeaves(int height) { 
    if (height == 2) {  // there is only a parent and two childs (leaves) 
     skip(1);    // skip 1 element 
     take(2);    // next two are leaves, get them 
    } 
    else { 
     skip(1);    // skip parent of parents (of parents ...) 
     getLeaves(height-1); // call on left part of array 
     getLeaves(height-1); // call on right part of array 
    } 
} 
+0

我認爲你需要使用BST財產作爲另一個答案建議。 – loremIpsum1771

+0

它不一定是一個「完美」的BST,仍然只有一個答案。因爲BST只有一個預訂遍歷。所以我們不能倒退,尋找葉節點。考慮預先遍歷899,999,1099,只有一個葉節點。 – Deep

-1
void printleafnode(int*arr, int size) 
{ 
    int i = 0; 

    while(i < size) 
    { 
     if(arr[i] > arr[i+1]) 
      i= i+1; 
     else 
     { 
      if(arr[i] < arr[i+1]) 
      { 
       printf(" %d " ,arr[i]); 
       i= i+1; 
      } 
     } 
    } 
    printf(" %d ", arr[i]); 
    printf("\n"); 
} 
+0

我對代碼塊進行了格式化,但它仍然缺少任何解釋,這使得它不是一個非常有用的答案。 – FTP

+0

雖然答案總是值得讚賞的,但是這個問題在6個月前被問過,並且已經有了一個可以接受的解決方案。請儘量避免通過提供答案來提出問題,除非問題還沒有被標記爲已解決,或者您發現了一個新的改進的解決方案。還請記住提供一些[**代碼圍繞您的代碼**](https://meta.stackexchange.com/questions/114762)來幫助解釋它。請查閱關於如何讓您的答案計數的一些提示的[**寫出很好的答案**](http://stackoverflow.com/help/how-to-answer)的文檔:) –

+0

複製粘貼從http:/ /www.geeksforgeeks.org/leaf-nodes-preorder-binary-search-tree/ – EmptyData

0
import java.util.ArrayList; 

public class PreorderArrayToTree { 

    static void printLeafNodes(ArrayList<Integer> list) { 
     if(list.size()==0)return; 
     if(list.size()==1) { 
      System.out.print(list.get(0)+" "); 
      return; 
     } 
     int parent = list.get(0); 
     ArrayList<Integer> leftChild = new ArrayList<Integer>(); 
     ArrayList<Integer> rightChild = new ArrayList<Integer>(); 
     for(int i=1; i<list.size(); i++) { 
      if(list.get(i)<parent)leftChild.add(list.get(i)); 
      if(list.get(i)>parent)rightChild.add(list.get(i)); 
     }; 
     printLeafNodes(leftChild); 
     printLeafNodes(rightChild); 
    }; 

    public static void main(String[] args) { 
     //int[] arr = {10,5,1,7,40,50}; 
     //int[] arr = {890, 325, 290, 530, 965}; 
     int[] arr = {3,2,4}; 
     ArrayList<Integer> list = new ArrayList<Integer>(); 
     for(int i=0; i<arr.length; i++)list.add(arr[i]); 
     printLeafNodes(list); 
    }; 
}; 
+0

你應該添加解釋你的代碼如何解決這個問題。 – moggi