1

在跳过列表中插入的算法是什么样的?

通常在谷歌上搜索时会弹出类似内容,但奇怪的是,我似乎在我的书或互联网上找不到任何有用的东西。

我唯一能找到的是关于跳过列表如何工作的解释。

4

1 回答 1

1

首先,我们需要为新元素找到一个位置(我称之为键)。

我们这样做:

  1. 让我们从最高级别开始,看看链接将我们引向何方。如果它导致列表的末尾或大于键的数字,我们需要向下一层。否则,我们跟随这个链接并重复这个链接指向我们的节点的过程。

  2. 每次我们无法跳转时,级别都会降低,并且每次可以跳转时列表中的位置都会增加,因此在有限数量的步骤之后,我们将达到级别零和从小于键的数字开始的链接到大于键的数字。这正是应该插入密钥的位置。

现在是时候插入它了。

  1. 让我们随机生成新节点的“高度”。

  2. 当我们在搜索过程中遍历列表时,我们可以保留一个数组来存储每个给定高度的最右边的链接。

  3. 对于从 0 到“高度”的每个级别,我们创建从该节点到最右边链接指向的节点的链接,并将最右边的链接重定向到新创建的节点。

我没有提到如何处理相等的元素。我们可以插入密钥(如果我们想存储重复项),或者忽略它。

下面是插入函数的伪代码:

class Node {
    // an array of links for levels from 0 to the height of this node
    Node[] next; 
    int key; 

    Node(int height, int key) {
        key = key;
        next = new Node[height + 1];
    }
}

// I assume that the list always has two nodes: head and tail, which do not
// hold any values

void insert(int newKey) {
    // The rightmost node for each level such that the node itself has a key 
    // less than newKey but the node which the link points to has a larger key. 
    rightMostForLevel = new Node[maxLevel + 1]
    fill(leftMostForLevel, head)
    curLevel = maxLevel
    curNode = head
    // We need to find a node with the largest key such that its key is less
    // than or equal to the newKey, but the next node in the list is either 
    // equal to the tail or a has a greater key. 
    // We are done when the level is equal to zero and the next node has 
    // a key greater than newKey.
    while (curLevel != 0 
            or (curNode.next[curLevel] != tail and curNode.next[curLevel] <= key)) {
        if (curNode.next[curLevel] == tail or curNode.next[curLevel].key > key) {
            // We cannot make the jump (its too "long")
            // So we go one level lower
            curLevel--
        } else {
            // Otherwise, we make the jump
            curNode = curNode.next[curLevel]
            // And update the rightmost node for the current level
            rightMostForLevel[curLevel] = curNode
        }
    }  
    // Now we know where the new node should be inserted 
    newHeight = random height
    newNode = new Node(newHeight, newKey)
    // All we need to do is to update the links
    for (level = 0; level <= newHeight; level++) {
        // We "cut" the links that go through the new node
        newNode.next[level] = rightMostForLevel[level].next[level] 
        rightMostForLevel[level].next[level] = newNode  
    }
}
于 2016-10-16T19:00:51.943 回答