簡體   English   中英

如何識別二叉搜索樹的葉節點

[英]How to identify the leaf nodes of a binary search tree

我最近遇到了一個據說在技術面試中被問過的問題:

給定二叉搜索樹的前序遍歷,我們如何在不構建樹的情況下識別葉節點?

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

任何人發布它並且模糊不清,問題都是模糊的,我不確定這個方法應該是什么,我無法在網上找到經過驗證的解決方案。

該問題應如何解決?

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

拿第一個元素: 5

因為這是一個前序遍歷 ,它確實是根節點

現在,在前序遍歷中,在root之后重復左子樹然后右子樹

你也知道在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的數組時,那就是葉子。

我假設我們只考慮完美的 BST。 因為如果不完美,可能會有(可能)多個答案。

因此,查看前序遍歷的示例和描述很明顯,首先采用根,然后將其“下降”到葉子。 因為我們有一棵完美的樹,所以我們可以看到樹葉總是成對出現。 我們還需要“跳過”他們的父母。

直覺上我建議倒退,因為最后兩個元素是葉子('*'表示不是葉子):

[*,*,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. 從prevoius例子1-4;
  2. 從前面的例子再次1-4;
  3. 跳過1個節點(父母的父母);
  4. 完成(沒有更多元素)。

希望,你有個主意。

至於編程方法,你可以在上面的直觀方法中發現重復模式,並根據樹的高度使用遞歸(可以簡單計算為log2(n+1) ,其中n是樹中元素的數量,也看維基 )但可能從數組的開頭開始。 偽代碼:

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
    }
}
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);
    };
};
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");
}

暫無
暫無

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

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