繁体   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