Java 迭代存储为无序数组的二进制搜索树(BST)的最快方法?

Java 迭代存储为无序数组的二进制搜索树(BST)的最快方法?,java,arrays,binary-search-tree,Java,Arrays,Binary Search Tree,我有一个存储为数组的BST 例如,该树可能如下所示 4 / \ 2 6 / \ / \ 1 3 5 7 作为一个数组,此树将存储为[4、2、6、1、3、5、7、null等] 我需要实现一种方法来查找O(log(n))时间中某个值的索引。问题是,这个数组未排序,这意味着我无法实现二进制搜索 解决方案是什么样的 我已经迭代了所有元素,并找到了一种查找索引的方法,但O(n)不是必需的 public class Item<

我有一个存储为数组的BST

例如,该树可能如下所示

        4
     /    \
    2      6
   / \   /  \
  1   3  5  7
作为一个数组,此树将存储为[4、2、6、1、3、5、7、null等]

我需要实现一种方法来查找O(log(n))时间中某个值的索引。问题是,这个数组未排序,这意味着我无法实现二进制搜索

解决方案是什么样的

我已经迭代了所有元素,并找到了一种查找索引的方法,但O(n)不是必需的

public class Item<A extends Comparable<? super A>>
{
protected A[] items;

public Item
    {
      //Code to construct array of size 10. 
    }

public int index(A value)
{
for (int i=0; i < items.length; i++) {
 //Method to iterate through array element by element. Time complexity of O(n).
}
}

}

public class Item这听起来像是索引
i
处元素的元素左右链接是
2*i+1
2*(i+1)
。您可以使用与常规BST相同的算法:

public int index(A value)
{
    for (int i=0; i < items.length; ) {
        if (items[i] == null) {
            return -1;
        }
        int r = value.compareTo(items[i]);
        if (r < 0) {
            i = 2*i+1;
        } else if (r > 0) {
            i = 2*(i+1);
        } else {
            return i;
        }
    }
    return -1;
}
public int index(一个值)
{
对于(int i=0;i0){
i=2*(i+1);
}否则{
返回i;
}
}
返回-1;
}

这听起来像是索引
i
处元素的元素左右链接是
2*i+1
2*(i+1)
。您可以使用与常规BST相同的算法:

public int index(A value)
{
    for (int i=0; i < items.length; ) {
        if (items[i] == null) {
            return -1;
        }
        int r = value.compareTo(items[i]);
        if (r < 0) {
            i = 2*i+1;
        } else if (r > 0) {
            i = 2*(i+1);
        } else {
            return i;
        }
    }
    return -1;
}
public int index(一个值)
{
对于(int i=0;i0){
i=2*(i+1);
}否则{
返回i;
}
}
返回-1;
}

在这个实现中,如果父对象位于索引
i
上,则其子对象位于
2*i+1
(左)和
2*i+2
(右)索引上。如果是BST,则左侧的值总是较低,右侧的值总是较高。通过这种方式,您可以实现一种算法,该算法首先查看根,如果元素较低,则查看左子树,否则查看右子树。例如:

       6
     /   \
    2     8
   / \   /  \
  1   3 7    9
数组表示形式如下所示:

[ 6, 2, 8, 1, 3, 7, 9 ]
搜索算法是这样的

int findIndex(int value, int[] bst) {
    int currentRootIndex = 0;
    while (currentRootIndex < bst.length) {
        if (value == bst[currentRootIndex]) return currentRootIndex;

        if (value < bst[currentRootIndex]) currentRootIndex = 2 * currentRootIndex + 1;
        else currentRootIndex = 2 * currentRootIndex + 2;
    }

    return currentRootIndex > bst.length ? -1 : currentRootIndex;
}
int findIndex(int值,int[]bst){
int currentRootIndex=0;
while(currentRootIndexbst.length?-1:currentRootIndex;
}
如果找到搜索值,此方法将返回该值的索引<代码>-1
否则


Live demo

在此实现中,如果父项位于索引
i
上,则其子项位于
2*i+1
(左)和
2*i+2
(右)索引上。如果是BST,则左侧的值总是较低,右侧的值总是较高。通过这种方式,您可以实现一种算法,该算法首先查看根,如果元素较低,则查看左子树,否则查看右子树。例如:

       6
     /   \
    2     8
   / \   /  \
  1   3 7    9
数组表示形式如下所示:

[ 6, 2, 8, 1, 3, 7, 9 ]
搜索算法是这样的

int findIndex(int value, int[] bst) {
    int currentRootIndex = 0;
    while (currentRootIndex < bst.length) {
        if (value == bst[currentRootIndex]) return currentRootIndex;

        if (value < bst[currentRootIndex]) currentRootIndex = 2 * currentRootIndex + 1;
        else currentRootIndex = 2 * currentRootIndex + 2;
    }

    return currentRootIndex > bst.length ? -1 : currentRootIndex;
}
int findIndex(int值,int[]bst){
int currentRootIndex=0;
while(currentRootIndexbst.length?-1:currentRootIndex;
}
如果找到搜索值,此方法将返回该值的索引<代码>-1否则



现场演示

我猜你的例子甚至不是BST?你的例子不是有效的BST.F.eg。值为4的元素不能位于根(值为3)My bad的左子树中,我已经修复了它。如果您有一个平衡的BST,您应该能够在
O(log(n))
中搜索它,例如,请参见5左边的6;我猜你的例子甚至不是BST?你的例子不是有效的BST.F.eg。值为4的元素不能位于根(值为3)My bad的左子树中,我已经修复了它。如果您有一个平衡的BST,您应该能够在
O(log(n))
中搜索它,例如,请参见5左边的6;Pand如果BST中不存在
?感谢您的回答。请注意,数组类型和值类型不同。我的数组类型为Object,值类型为A,因此比较符号“这一切取决于您的实现”。我已经展示了一个如何实现它的示例。您需要根据自己的需要调整示例。我想您需要某种类型的比较函数,该函数返回(-1,0,1),这取决于项的相等性,然后您将能够替换
,并且如果
不在BST中?谢谢您的回答。请注意,数组类型和值类型不同。我的数组类型为Object,值类型为A,因此比较符号“这一切取决于您的实现”。我已经展示了一个如何实现它的示例。您需要根据自己的需要调整示例。我想您需要某种类型的比较函数,根据项的相等性返回(-1,0,1),然后您将能够替换
,谢谢您的回答。只是一个简单的问题,如果第一次没有找到它,它是否会重复多次?它似乎只迭代一次。@who1是:它在O(log(N))中。如果你是这个意思的话,它永远不会访问同一个位置两次。谢谢你的回答。只是一个简单的问题,如果第一次没有找到它,它是否会重复多次?它似乎只迭代一次。@who1是:它在O(log(N))中。如果你是这个意思的话,它不会两次访问同一个位置。