算法:在跳过列表中插入

时间:2016-10-16 18:45:51

标签: algorithm computation-theory skip-lists

跳过列表中的插入算法如何?

在Google上搜索时,通常会出现类似this的内容,但奇怪的是,我似乎无法在我的书或互联网上找到任何有用的内容。

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

1 个答案:

答案 0 :(得分:1)

首先,我们需要找到新元素的位置(我将其称为键)。

我们这样做:

  1. 让我们从最高级别开始,看看链接引导我们的位置。如果它导致列表的末尾或大于键的数字,我们需要降低一级。否则,我们将按照此链接重复此链接引导我们的节点的过程。

  2. 每次我们无法跳跃时水平降低,并且每次我们可以增加列表中的位置,因此在有限步骤之后我们将达到零水平并且从数字引出一个链接这小于密钥数量的关键字。它正好应该插入密钥的位置。

  3. 现在是时候插入它了。

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

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

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

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

      这是插入函数的伪代码:

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