【问题标题】:How to find the index of the maximum value in a Binary Search Tree array implementation?如何在二叉搜索树数组实现中找到最大值的索引?
【发布时间】:2021-11-15 03:49:47
【问题描述】:

我有三个类似于此示例的数组:

左右数组是当前索引的左右子节点的索引号。如果其中任何一个持有 -1,则该孩子不存在。如果两者都保持-1,则索引处的节点是叶子。我知道这在现实世界中实现起来并没有什么意义,但这是为了分配。

无论如何,我正在尝试在实现此想法的类中实现 remove 方法。除了节点有两个孩子的情况外,我让它适用于所有事情。我的问题是我正在调用一个递归方法(我创建的所有方法都必须是递归的),该方法应该返回包含我要删除的节点的左子树中最大节点的索引。我需要这个,因为这是将用两个正在删除的子节点替换节点的节点。

我当前的代码返回它在子树中看到的第一个节点的索引,因为我的返回实际上被覆盖了。见这里:

//find largest node in left subtree and return its index
private int findNew(int index) {
    int r = right[index];
    if(r != -1) {
        findNew(r);
    }
    return index;
}

这是我实现的删除方法:

private void remove(int d, int index) {
    //we found the data to remove
    if(data[index] == d){
    //removes
        //if the node is a leaf
        if(left[index] == -1 && right[index] == -1) {
            data[index] = -1;
            if(free == -1) {
                free = index;
            } else {
                freeUpdate(index);
            }
            currentSize--;
        }
        //the node has a left child
        else if(left[index] != -1 && right[index] == -1) {
            int l = left[index];
            data[index] = data[l];
            left[index] = left[l];
            right[index] = right[l];
            if(free == -1) {
                free = l;
            } else {
                freeUpdate(l);
            }
            //delete stuff in node that moved
            data[l] = -1;
            right[l] = -1;
            currentSize--;
        }
        //the node has a right child
        else if(left[index] == -1 && right[index] != -1) {
            int r = right[index];
            data[index] = data[r];
            left[index] = left[r];
            right[index] = right[r];
            if(free == -1) {
                free = r;
            } else {
                freeUpdate(r);
            }
            //delete stuff in node that moved
            data[r] = -1;
            right[r] = -1;
            currentSize--;
        }
        //the node has two children
        else {
            int l = left[index];
            int r = right[index];
            int newParent = findNew(l);
            //implement the rest of the remove here
            currentSize--;
        }
    } else {
        //if we have searched the entire tree
        if(index == data.length) {
            return;
        } else {
            //keep searching for d
            remove(d, index + 1);
        }
    }
}

类的属性和构造函数:

private int root;
private int free;
private int left[];
private int data[];
private int right[];
private int currentSize;

public BoundedBST(int size) {
    root = -1;
    free = -1;
    left = new int[size];
    data = new int[size];
    right = new int[size];
    currentSize = 0;
}

public boolean full() {
    return free == -1 && currentSize == data.length;
}

我再次知道这个实现没有多大意义,但这是我正在使用的。我知道 findNew 方法可以很容易地通过使用循环来完成,但我不能在这里这样做。

基本上我只是想找到一种方法让我的 findNew 方法递归地工作,而不会覆盖最后一次调用返回的内容。我理解这里发生的错误,但我不知道如何实现这样一个仍然可以具有非 void 返回类型的函数。

【问题讨论】:

  • 你想获取作为参数传递的节点的最大左子树的索引。我的问题是要知道传入参数的节点的左子树的所有子树(左右)是否都会受到搜索的影响?

标签: java arrays binary-search-tree


【解决方案1】:

findNew 的问题在于,当您进行递归调用时,您不会对该递归调用返回的内容做任何事情。该值将被忽略,并且您在 所有 情况下返回 index。这使得递归调用无用。

您实际上应该捕获该返回值,并将其再次返回给调用者,以便该索引从递归调用中冒出来,直到它到达原始调用者。

我还建议给这个函数一个更具描述性的名称:findGreatest:

private int findGreatest(int index) { // Use a better name
    int r = right[index];
    if (r != -1) {
        return findGreatest(r); // Must do something with the value returned!
    }
    return index;
}

这解决了您询问的问题。但是您仍然需要完成您编写的部分“在此处实现其余的删除”。我建议你努力。如果您在执行此操作时遇到具体问题,请随时提出新问题。

最后,在确定一切正常之前,请确保在许多不同的场景中彻底测试您的解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-23
    • 1970-01-01
    • 2011-03-10
    • 2019-02-20
    相关资源
    最近更新 更多