JavaScript AVL树-删除带有子节点的节点

时间:2020-09-04 01:30:22

标签: javascript recursion avl-tree

我正在用JavaScript实现管理AVL树的FAST方式: 创建平衡树很容易,但是,删除节点似乎是一个问题:

我在寻找有关删除AVL节点的明确解释,并找到了许多删除LEAF节点的解释。我的担心:如果我想从中间删除节点怎么办?

我的方法是:

// n is the node to be deleted
// each node has "k" property which is the key which sorting is done based on.

if(n.parent) {
    if(n.parent.k>n.k) { // we are the left side of parent
        // link the biggest value (right) to parent:
        n.parent.left=n.right||n.left; // but if has no n.right, than take n.left
        n.right.parent=n.parent; // link the parent to that child
    }
    else {
        // do the same to the other side (just opposite)
        n.parent.right=n.left||n.right; n.left.parent=n.parent;
    }
}
else { // if no parent, then n is root
    this.db=n.right||n.left; // put the right child as root, or the left one if the right is missing.
    if(n.right) { delete n.right.parent; if(n.left) n.left.parent=n.right; } // update link
    else if(n.left) delete n.left.parent;
}

// !!! balancing???!!!

问题:

  1. 从叶子中删除很容易,但也需要保持平衡。从树的中心删除需要更多的平衡,但是我不知道如何从这一点开始...考虑使del()递归...
  2. 如果我要使del()递归,是否需要“拉起”所有节点,直到到达第一个叶子,然后删除?我担心的是,除非没有其他方法,否则此操作很耗时,甚至可能是错误的。

注意:我没有在节点中保持平衡因子,因为这需要不断更新,我发现在JS中调用gH之类的函数要快得多-测试的100000条记录用了15秒函数getHeight()实现平衡因子和0.9秒-我不知道为什么。

更正: 上面的方法是错误的,我发现需要循环遍历到叶的节点,并用叶之一替换“删除”节点-仍然需要建立此算法。我的理解是,平衡开始于向上的叶节点,但也许我错了……据我所知,我不应该在“已删除的节点”中停止递归,而应该向上移至根节点。

常规实施代码:

// Rotations
function rotateLeft(a) {
    var n=a.right; a.right=n.left; a.right.parent=a; n.left=a; return n;
}
function rotateRight(a) {
    var n=a.left; a.left=n.right; a.left.parent=a; n.right=a; return n;
}
function rotateLeftRight(a) {
    a.right=rotateLeft(a.right);
    return rotateRight(a);
}
function rotateRightLeft(a) {
    a.left=rotateRight(a.left);
    return rotateLeft(a);
}

// Get tree height at specific node
function getHeight(n) {
    if(!n) return 0;
    var l=getHeight(n.left),r=getHeight(n.right);
    return (l>r?l:r)+1;
}

// Do balancing as per situation:
function bal(n) {
    if(!n) return; var b=getHeight(n.left),e=getHeight(n.right);
    if(b-e>1) 
        return (getHeight(n.left.left)>=getHeight(n.left.right)?rotateRight(n):rotateRightLeft(n));
    if(e-b>1)
        return (getHeight(n.right.right)>=getHeight(n.right.left)?rotateLeft(n):rotateLeftRight(n));
    return n;
}

// Add single node
this.add=function(v,n) {
    // v = single node data. contents permited:
    //      k = key (based on which will do sorting)
    //      v = internal value (optional)
    if(!this.db) { this.db=v; return; } if(!n) n=this.db;
    if(v.k<n.k)
        if(!n.left) { v.parent=n; n.left=v; n.left=bal(n.left); }
        else this.add(v,n.left);
    else
        if(!n.right) { v.parent=n; n.right=v; n.right=bal(n.right); }
        else this.add(v,n.right);
};

// And the problem comming:
this.del=function(n) { ... }

非常感谢您的帮助

0 个答案:

没有答案
相关问题