简体   繁体   English

如何在二叉搜索树数组实现中找到最大值的索引?

[英]How to find the index of the maximum value in a Binary Search Tree array implementation?

I have three arrays that look like this sample:我有三个看起来像这个示例的数组: 在此处输入图片说明

The left and right arrays are the index numbers for the left and right children of the current index. left 和 right 数组是当前索引的左右孩子的索引号。 If either holds -1, that child doesn't exist.如果任一持有 -1,该孩子不存在。 If both hold -1, the node at the index is a leaf.如果两者都保持 -1,则索引处的节点是叶节点。 I know this doesn't really make sense to implement in a real-world scenario but this is for an assignment.我知道这在现实世界中实施并没有什么意义,但这是一项任务。

Anyways I am trying to implement a remove method within a class that implements this idea.无论如何,我试图在实现这个想法的类中实现一个 remove 方法。 I have it working for everything but the case where a node has two children.除了节点有两个孩子的情况外,我让它适用于所有情况。 My issue here is that I am making a call to a recursive method (all methods I create must be recursive) that is supposed to return the index that holds the largest node in the left subtree of the node I am removing.我的问题是我正在调用一个递归方法(我创建的所有方法都必须是递归的),该方法应该返回包含我要删除的节点左子树中最大节点的索引。 I need this as this is the node that will be replacing the node with two children that is being removed.我需要这个,因为这是将用正在删除的两个子节点替换节点的节点。

My current code returns the index of the first node it sees in the subtree, as my returns are essentially being overwritten.我当前的代码返回它在子树中看到的第一个节点的索引,因为我的返回基本上被覆盖了。 See here:看这里:

//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;
}

Here is the remove method I have implemented:这是我实现的删除方法:

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

Attributes and constructor for the class:类的属性和构造函数:

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

Again I know this implementation does not make much sense, but it's what I am working with.我再次知道这个实现没有多大意义,但这就是我正在使用的。 I know the findNew method can be done very easily by using a loop, but I'm not able to do so here.我知道使用循环可以很容易地完成 findNew 方法,但我不能在这里这样做。

Essentially I am just trying to find a way for my findNew method to work recursively without overwriting what was returned from the very last call.本质上,我只是想找到一种方法,让我的 findNew 方法递归工作,而不会覆盖上次调用返回的内容。 I understand the error that is occurring here, but I don't know how else to implement such a function that can still have a non-void return type.我理解这里发生的错误,但我不知道如何实现这样一个仍然可以具有非 void 返回类型的函数。

The problem with findNew is that when you make the recursive call, you don't do anything with what that recursive call returns. findNew的问题在于,当您进行递归调用时,您不会对递归调用返回的内容做任何事情。 That value is ignored, and you return index in all cases.该值将被忽略,并且您在所有情况下返回index This makes the recursive call useless.这使得递归调用无用。

You should actually capture that return value, and return it again to the caller, so that this index bubbles up out of the recursive calls until it reaches the original caller.您实际上应该捕获该返回值,并将其再次返回给调用者,以便该索引从递归调用中冒泡出来,直到它到达原始调用者。

I would also suggest to give this function a more descriptive name: findGreatest :我还建议给这个函数一个更具描述性的名称: 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;
}

This fixes the issue you ask about.这解决了您询问的问题。 But you still need to complete the part where you wrote "implement the rest of the remove here" .但是你仍然需要完成你写的“在此处实现其余的删除”部分 I suggest you work on that.我建议你在这方面努力。 If you bump into specific problems doing that, feel free to ask a new question about that.如果您在执行此操作时遇到特定问题,请随时提出有关该问题的新问题。

Finally, make sure you test your solution thoroughly, on many different scenario's, before deciding all is good.最后,在决定一切都好之前,请确保在许多不同的场景下彻底测试您的解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM