可以使用什么数据结构/算法在JavaScript中检索一对值(前后)

可以使用什么数据结构/算法在JavaScript中检索一对值(前后),javascript,algorithm,data-structures,Javascript,Algorithm,Data Structures,可以使用什么数据结构和/或算法来检索一对值(在搜索值之前和之后)。搜索值不需要在元素列表中。我开始使用BST,但叶节点出现了一些问题。该实现是针对客户端javascript的 这是当前代码: var structs = (function structs() { function Node(value) { return { value: value, left: null, right: null

可以使用什么数据结构和/或算法来检索一对值(在搜索值之前和之后)。搜索值不需要在元素列表中。我开始使用BST,但叶节点出现了一些问题。该实现是针对客户端javascript的

这是当前代码:

var structs = (function structs() {
    function Node(value) {
        return {
            value: value,
            left: null,
            right: null
        };
    }

    function BSTree() {
        this.root = null;
    }

    BSTree.prototype = {
        constructor: BSTree,

        add: function (value) {
            var newNode = new Node(value),
                current;

            if (this.root === null) {
                this.root = newNode;
            } else {
                current = this.root;
                while (true) {
                    if (value > current.value) {
                        if (current.right === null) {
                            current.right = newNode;
                            break;
                        } else {
                            current = current.right;
                        }
                    } else if (value < current.value) {
                        if (current.left === null) {
                            current.left = newNode;
                            break;
                        } else {
                            current = current.left;
                        }
                    } else {
                        break;
                    }
                }
            }
        },

        valuesBeforeAfter: function (value) {
            var current = this.root,
                values = {
                    before: null,
                    after: null
                };

            function getAfter(node) {
                var value = null;
                while (node) {
                    value = node.value;

                    if (node.left) {
                        node = node.left;
                    } else {
                        node = null;
                    }
                }

                return value;
            }

            function getBefore(node) {
                var value = null;
                while (node) {
                    value = node.value;

                    if (node.right) {
                        node = node.right;
                    } else {
                        node = null;
                    }
                }

                return value;
            }

            function isBefore(before) {
                return value - before === 1;
            }

            function isAfter(after) {
                return after - value === 1;
            }

            while (current) {
                if (value < current.value) {
                    if (values.after && isAfter(values.after)) {
                        current = current.left;
                    } else {
                        values.after = current.value;

                        if (current.left && !isBefore(values.before)) {
                            values.before = getBefore(current.left);
                        }

                        current = current.left;
                    }
                } else if (value > current.value) {
                    if (values.before && isBefore(values.before)) {
                        current = current.right;
                    } else {
                        values.before = current.value;

                        if (current.right && !isAfter(values.after)) {
                            values.after = getAfter(current.right);
                        }

                        current = current.right;
                    }
                } else { // problem when the node is also a leaf and not left or right
                    if (current.right && current.left) {
                        values.before = getBefore(current.left);
                        values.after = getAfter(current.right);
                    } else {
                        if (!current.right && !isAfter(values.after)) {
                            values.after = null;
                        }

                        if (!current.left && !isBefore(values.before)) {
                            values.before = null;
                        }

                        if (current.left) {
                            values.before = getBefore(current.left);
                        }

                        if (current.right) {
                            values.after = getAfter(current.right);
                        }
                    }

                    current = null;
                }
            }

            if (values.before > value) {
                values.before = null;
            }

            if (values.after < value) {
                values.after = null;
            }

            return values;
        }
    };

    return {
        BSTree: BSTree
    }
})();

注意:函数/方法
valuesBeforeAfter
应始终返回至少一个值,除非结构为空。该结构将只保存整数值,并且在设置之后它将永远不会更改。

排序数组可以完成二进制搜索树所能完成的所有操作,除了更新。因为您不需要这些,所以只需使用排序数组和简单的二进制搜索:)

var值=[4,1,3,5,9,6,2];
value.sort();
//假定值已排序且非空
函数值在(x){
var lo=0,hi=values.length;
while(lo>1;
如果(值[mid]>x)hi=mid;
否则lo=mid+1;
}
//lo将是第一个元素>x的索引
//如果不存在这样的元素,则为value.length
控制台日志(lo);
if(lo==values.length)返回[values[lo-1],null];
else if(lo==0)返回[null,值[lo]];
否则返回[value[lo-1],value[lo]];
}

在调用
值之前的
调用之间,您是否也添加
删除
?或者它在设置后从未更改?在设置后结构从未更改我认为您的解决方案有问题,如果您使用6测试函数,它返回[1,null],它应该返回[5,9],请记住它必须在设置前后立即检索values@RamónGarcía-Pérez:它返回
[6,9]
,,我认为这是正确的。如果左索引相等,可以很容易地减小它的值。请看,它与按升序排序的数组一起工作,与按降序排序的数组一起尝试。
var bst, values;

bst = new BSTree();  
bst.add(4);  
bst.add(1);  
bst.add(3);  
bst.add(5);  
bst.add(9);  
bst.add(6);  
bst.add(2);  
values = bst.valuesBeforeAfter(6); // before = 5; after = null; wrong after should be 9
values = bst.valuesBeforeAfter(7); // before = 6; after = 9;
var values = [4,1,3,5,9,6,2];
values.sort(); 

// assumes that values is sorted and non-empty
function valuesBeforeAfter(x) { 
    var lo = 0, hi = values.length;
    while (lo < hi) {
        var mid = (lo + hi) >> 1;
        if (values[mid] > x) hi = mid;
        else                 lo = mid + 1;
    }
    // lo will be the index of the first element > x 
    // or values.length if no such element exists
    console.log(lo);
    if (lo == values.length) return [values[lo - 1],   null]; 
    else if (lo == 0)        return [null,             values[lo]];
    else                     return [values[lo - 1],   values[lo]];
}