Data Structures, Algorithms, & Applications in Java
Chapter 11, Exercise 9

Before we can delete the minimum element, we must verify that the structure is not empty. When we have at least one element in the skip list, the minimum element is the first one in the level 0 chain. Therefore, the minimum element can be removed by the invocation remove(headNode.next[0].key).

Before we can delete the maximum element, we need to verify that such an element exists. This is so iff the structure is not empty. If there is a max element, it is in the last node on the level 0 chain. The max element is in the node with next[0] equal to tailNode. We can find this node by invoking search(tailKey). Following this invocation, last[0] points to the node just before the tail. This node contains the max element. This max element may be removed using the invocation return remove(last[0].key).

The code that implements the above strategy is given below.


public class ExtendedSkipList1 extends SkipList
{
   // constructor
   public ExtendedSkipList1(Comparable largeKey, int maxElements, float theProb)
      {super(largeKey, maxElements, theProb);}

   /** @return element with smallest key and remove it
     * @return null if no element */
   public Object removeMinElement()
   {
      // make sure there is a min element
      if (headNode.next[0] == tailNode)
         // dictionary is empty
         return null;
   
      // remove the minimum element
      return remove(headNode.next[0].key); // min key
   }
   
   /** @return element with largest key and remove it
     * @return null if no element */
   public Object removeMaxElement()
   {
      // make sure there is a maximum element
      if (headNode.next[0] == tailNode)
         // dictionary is empty
         return null;
    
      // search for tail key
      search(tailKey);
      // remove element with largest key
      return remove(last[0].key);
   }
}

The call to remove in the above code for removeMinElement results in a search for the element with key theKey and the setting of the array last. This is unneccessary as we know that the element is in headNode.next[0] and that all last values are headNode. So we can eliminate the work done by the search that is invoked by remove and tailor the remainder of the code in remove to our situtaion.

We can also make the code for removeMax more efficient. The new, more efficient, codes are given below.


public class ExtendedSkipList2 extends SkipList
{
   // constructor
   public ExtendedSkipList2(Comparable largeKey, int maxElements, float theProb)
      {super(largeKey, maxElements, theProb);}

   /** @return element with smallest key and remove it
     * @return null if no element */
   public Object removeMinElement()
   {
      // make sure there is a min element
      if (headNode.next[0] == tailNode)
         // dictionary is empty
         return null;
   
      // save pointer to node with min element
      SkipNode minNode = headNode.next[0];
   
      // remove minNode from structure
      for (int i = 0; i <= levels &&
               headNode.next[i] == minNode; i++)
         headNode.next[i] = headNode.next[i].next[i];
   
      // update levels
      while (levels > 0 && headNode.next[levels] == tailNode)
         levels--;
   
      // return min element
      return minNode.element;
   }
   
   /** @return element with largest key and remove it
     * @return null if no element */
   public Object removeMaxElement()
   {
      // make sure there is a maximum element
      if (headNode.next[0] == tailNode)
         // dictionary is empty
         return null;
    
      // search for max element
      SkipNode y = headNode;
      for (int i = levels; i >= 0; i--)
         while (y.next[i] != tailNode)
            y = y.next[i];
   
      // remove element with largest key
      return remove(y.key);
   }
}



The expected complexity of removeMinElement and removeMaxElement is O(log n). Here n is the number of elements in the skip list.

The test programs and output are in the files ExtendedSkipList1.* and ExtendedSkipList2.*.