reference:http://www.mathcs.emory.edu/~cheung/Courses/323/Syllabus/Map/skip-list-impl.html

  • The link list element structure used to implement a Skip List

    • The link list element used to implement the skip list has 4 links (not including the data portion):





  • The Entry strcuture in a Skip List (the SkipListEntry class)
    • Skip List entry:

        public class SkipListEntry
      {
      public String key;
      public Integer value; public SkipListEntry up; // up link
      public SkipListEntry down; // down link
      public SkipListEntry left; // left link
      public SkipListEntry right; // right link ...
      (methods)
      }

      Note:

      • As you can see, my entry type is again very specific (no generic types):

        • String key
        • Integer value

      • When I write the demo program, I will do it using specific types (classes)not parameterized classes

        I have showed you how to convert a specific class into a parameterized class, so you can write one if you want to


      • Reason for using specific classes:
        • My choice is didactic in nature; I don't want to spend time analyzing the overly complex syntax of parameterized classes
        • I want to spend my time teaching algorithms, not Java syntax




  • Making (and using) the special −∞ and +∞ elements
    • Representing the −∞ element and the +∞ element:

      • The −∞ and the +∞ is just an ordinary Skip List Entry containing a special value for the key field.

    • We can accommodate the −∞ element and the +∞ element by defining 2 special key value:
        public class SkipListEntry
      {
      public String key;
      public Integer value; public SkipListEntry up, down, left, right; public static String negInf = "-oo"; // -inf key value
      public static String posInf = "+oo"; // +inf key value ....
      }

    • How to instantiate a Skip List entry containing +∞:
           SkipListEntry x = new SkipListEntry( SkipListEntry.posInf, null );
      

      How to check if an Skip List entry x contains +∞:

             key == SkipListEntry.posInf
      




    OK, now we move on to the Skip list itself....





  • Structure (class) to represent a Skip List
    • Remember that a Skip List is a very complicated list

      But.... It is never the less a list

      • To represent a list, we only use a pointer (that points to the first element)
      • Often, we use more pointers for improve efficiency (such as a tail pointer)

    • Variables in the SkipList class:
         public class SkipList
      {
      public SkipListEntry head; // First element of the top level
      public SkipListEntry tail; // Last element of the top level public int n; // number of entries in the Skip List public int h; // Height
      public Random r; // Coin toss .... }

      Note:

      • The Random object r is used to determine the height of a newly added entry

        (We use r to simulate a coin toss experiment)


    • Example illustrating how the variables are used:

      Note:

      • Since the logical top level does not contain any entries:

        • The implementation will omit the logical top layer

      • The variables head and tail provide quick access to the end elements of the real top layer

        Usage of head and tail:

        • They allow us to easily add an new layer above the top layer




  • Constructing a Skip List object
    • The constructor will construct an empty Skip List which looks like this:

    • Constructor code:
        public SkipList()     // Constructor...
      {
      SkipListEntry p1, p2; /* -----------------------------------
      Create an -oo and an +oo object
      ----------------------------------- */
      p1 = new SkipListEntry(SkipListEntry.negInf, null);
      p2 = new SkipListEntry(SkipListEntry.posInf, null); /* --------------------------------------
      Link the -oo and +oo object together
      --------------------------------------- */
      p1.right = p2;
      p2.left = p1; /* --------------------------------------
      Initialize "head" and "tail"
      --------------------------------------- */
      head = p1;
      tail = p2; /* --------------------------------------
      Other initializations
      --------------------------------------- */
      n = 0; // No entries in Skip List
      h = 0; // Height is 0 r = new Random(); // Make random object to simulate coin toss
      }

    • The SkipList class so far:
         public class SkipList
      {
      public SkipListEntry head; // First element of the top level
      public SkipListEntry tail; // Last element of the top level public int n; // number of entries in the Skip List public int h; // Height
      public Random r; // Coin toss public SkipList() // Constructor...
      {
      SkipListEntry p1, p2; p1 = new SkipListEntry(SkipListEntry.negInf, null);
      p2 = new SkipListEntry(SkipListEntry.posInf, null); head = p1;
      tail = p2; p1.right = p2;
      p2.left = p1; n = 0; h = 0;
      r = new Random();
      } ...
      }




  • Implementing the basic Map operations
    • Basic Map operations:

      • get()
      • put()
      • remove()

      Notice that each basic operation must first find (search) the appropriate entry (using a key) before the operation can be completed.

      So we must learn how to search a Skip List for a given key first....





  • Search operation in a skip list
    • Consider the links traversed to locate the key 50:


    • Psuedo code:
         p = head;
      
         repeat
      { Move to the right until your right neighbor node
      contains a key that is greater than k if ( not lowest level )
      Drop down one level
      else
      exit
      }

    • Search algorithm for Skip List:
        /* ------------------------------------------------------
      findEntry(k): find the largest key x <= k
      on the LOWEST level of the Skip List
      ------------------------------------------------------ */ public SkipListEntry findEntry(String k)
      {
      SkipListEntry p; /* -----------------
      Start at "head"
      ----------------- */
      p = head; while ( true )
      {
      /* ------------------------------------------------
      Search RIGHT until you find a LARGER entry E.g.: k = 34 10 ---> 20 ---> 30 ---> 40
      ^
      |
      p must stop here
      p.right.key = 40
      ------------------------------------------------ */
      while ( (p.right.key) != SkipListEntry.posInf &&
      (p.right.key).compareTo(k) <= 0 )
      {
      p = p.right; // Move to right
      } /* ---------------------------------
      Go down one level if you can...
      --------------------------------- */
      if ( p.down != null )
      {
      p = p.down; // Go downwards
      }
      else
      {
      break; // We reached the LOWEST level... Exit...
      }
      } return(p); // Note: p.key <= k
      }

    • Note:
      • If the key k is found in the Skip ListfindEntry(k) will return the reference to the entry containg the key k


      • If the key k is not found in the Skip ListfindEntry(k) will return the reference to the floorEntry(k) entry containg a key that issmaller than k

        Example: findEntry(42) will return the reference to 39:





  • Implementing the "get(Key k)" method
    • get(k):

        /** Returns the value associated with a key. */               
      
        public Integer get (String k)
      {
      SkipListEntry p; p = findEntry(k); if ( k.equals( p.key ) )
      return(p.value);
      else
      return(null);
      }








  • Put(k,v): inserting into a Skip List
    • Pseudo code for put(k,v):

          put(k, v)
      {
      SkipListEntry p; p = findEntry(k); if ( k.equals( p.key ) ) // Found !
      {
      p.value = v; // Update the value
      return; // Done
      } /* ==================================================
      Not found. Then: p == floorEntry(k) !!!
      ================================================== */ (1) insert (k,v) AFTER p
      (2) make a column of (k,v) of RANDOM height
      }


    • Recall what happens when we insert a new entry:
      • Before insertion:


      • After inserting key 42:

        Note:

        • As part of the insert operation, we will make a column (see figure above) for that key


        • The height of the column will be random...

          (We have also seen how to use a random "trial" to generate a random height)



    • Step-by-step depictions of the steps necessary for insertion: put("42", ??)
      • Before the insertion:


      • Step 1: find the insert position

        p = findEntry(k)


      • Step 2: insert q after p:




      • Now make a column of random heightrepeat these steps a random number of times
        • Starting at p, (using p to) scan left and find the first entry that has an up-entry:

          Make p point to the up-element:



        • Create a new entry with the same key (we are making the "tower"):

        • Insert the newly created entryright of p and up from q:

        • Make q point to the newly inserted entry (to continue the iteration if necessay)

      • I will repeat the steps and show the effect of building a "tower":
        • Starting at pscan left and find the first entry that has an up-element:


        • Create a new entry (we are making another level of the "tower"):

        • Insert the newly created entryright of p and up from q:

        • Make q point to the newly inserted entry (to continue the iteration if necessay)

          (And so on)


    • Note:
      • If the height of the "tower" is = h:

        we must add an new empty layer before we can insert another entry:





  • Adding a (empty) layer
    • Before we can do anything, We need to what are the changes in the Skip List when we add an empty layer to the Skip List:

      • Here is the Skip List before we add a new (empty) top layer:


      • Here is the Skip List before we add a new (empty) top layer:

    • Add layer algorithm:
         SkipListEntry p1, p2;
      
         /* -----------------------------
      Make the -oo and +oo entries
      ---------------------------- */
      p1 = new SkipListEntry(SkipListEntry.negInf, null);
      p2 = new SkipListEntry(SkipListEntry.posInf, null); /* --------------------
      Link them
      -------------------- */
      p1.right = p2;
      p1.down = head; p2.left = p1;
      p2.down = tail; head.up = p1;
      tail.up = p2; /* --------------------
      Update head and tail
      -------------------- */
      head = p1;
      tail = p2; h = h + 1; // One more level...






  • The put() method
    • put(k,v) psuedo code:

           p = findEntry(k);         // Find insert location
      
           if ( entry found )
      {
      update the value in p;
      exit;
      } /* ----------------------------------
      Insert a brand new entry (k,v) p put q here
      | |
      V V
      [ ] <------> [ ]
      ---------------------------------- */ q = new Entry(k,v); // Make new entry
      link q after p; /* ------------------------
      Make a random tower...
      ------------------------ */
      while ( random() < 0.5 /* coin toss */ )
      {
      if ( height of tower >= h )
      {
      create a new TOP layer (see: click here)
      } p = Find the first left element in the next level above; q = new Entry(k,v);
      link q after p;
      }



    • The put() method for Skip List in Java:
        public Integer put (String k, Integer v)
      {
      SkipListEntry p, q;
      int i; p = findEntry(k); // Try find the entry /* ------------------------
      Check if key is found
      ------------------------ */
      if ( k.equals(p.key) ) // If key found, update the value and we are done...
      {
      Integer old = p.value; // Remember the old value p.value = v; // Update value return(old); // Return the old value
      } /* -------------------------------------------------------------
      Key k is not found, then p = floorEntry(k) (See: click here) The rest of the code will insert a new entry (k,v)
      ------------------------------------------------------------- */ q = new SkipListEntry(k,v); // Create a new entry with k and v /* --------------------------------------------------------------
      Insert q into the lowest level after SkipListEntry p: p put q here p q
      | | | |
      V V V V V
      Lower level: [ ] <------> [ ] ==> [ ] <--> [ ] <--> [ ]
      --------------------------------------------------------------- */
      q.left = p;
      q.right = p.right;
      p.right.left = q;
      p.right = q; /* -----------------------------------------------------
      Make a "tower" of the entry e or RANDOM height
      ----------------------------------------------------- */ i = 0; // Current level = 0 while ( r.nextDouble() < 0.5 /* Coin toss */ )
      {
      // Coin toss success ! ---> build one more level !!! /* -------------------------------------------------------------------
      Check if we need to increase the height of the -oo and +oo "pillars
      ------------------------------------------------------------------- */
      if ( i >= h ) // We reached the top level !!!
      {
      Create a new empty TOP layer
      (see: click here)
      (Put the code from above here.... I left it out for brevity)
      } /* ------------------------------------
      Find first element with an UP-link
      ------------------------------------ */
      while ( p.up == null )
      {
      p = p.left;
      } /* --------------------------------
      Make p point to this UP element
      -------------------------------- */
      p = p.up; /* ---------------------------------------------------
      Add one more (k,*) to the column Schema for making the linkage: p <--> e(k,*) <--> p.right
      ^
      |
      v
      q
      ---------------------------------------------------- */
      SkipListEntry e; e = new SkipListEntry(k, null); // Don't need the value... /* ---------------------------------------
      Initialize links of e
      --------------------------------------- */
      e.left = p;
      e.right = p.right;
      e.down = q; /* ---------------------------------------
      Change the neighboring links..
      --------------------------------------- */
      p.right.left = e;
      p.right = e;
      q.up = e; q = e; // Set q up for next iteration (if there is one)
      // See here for more detail: click here i = i + 1; // Current level increases by one
      } n = n + 1; // One more entry in the Skip List return(null); // No old value
      }

    • Example Program: (Demo above code)                                                 

      Example output: (The keys are strings)

       -  -  -  -  -  -  -  -  -  -
      10
      13
      15 15
      2
      21
      25
      31 31 31
      33 33 33 33 33 33 33 33 33 33
      36
      38
      39 39 39 39 39
      41 41 41
      42 42 42 42
      5 5 5
      54 54
      57
      59 59 59 59 59 59 59
      60 60
      63 63
      65
      69
      7
      71 71 71 71 71
      72
      77 77
      81
      82
      86
      88
      90
      92 92
      99
      + + + + + + + + + +




  • Deleting an entry from a Skip List
    • What you must do to the skip list to remove an entry:

      • Before deletinng the entry 25:


      • After deleting the entry 25:

        (The whole column containing entries for 25 must be deleted !!!)




    • Step-by-step to accomplish: remove(25)
      • Before the deletion:


      • Step 1: locate the desired element (at the lowest level of the skip list):

      • While p != null, repeat these steps to remove the column:
        • Unlink the element at p (by making the left neighbor and the right neighbor pointing to each other)


        • Move p upward (prepare for loop)


      • Result of removal:




  • The Removal Algorithm
    • Psuedo code:

         p = findExntry(k);
      
         if (p.key != k)
      return(null); // Not found, don't remove /* ------------------------------------------------------------
      We are at level 0
      Travel up the tower and link the left and right neighbors
      ------------------------------------------------------------ */
      while ( p != null )
      {
      p.left.right = p.right;
      p.right.left = p.left;
      }

      补充,jdk中有一个java.util.concurrent.ConcurrentSkipListMap,可以参考这个skiplist实现。

    • * @author Doug Lea
      * @param <K> the type of keys maintained by this map
      * @param <V> the type of mapped values
      * @since 1.6

Implementing the skip list data structure in java --reference的更多相关文章

  1. Data structure basics - Java Implementation

    Stack & Queue Implementations FixedCapacityQueue package cn.edu.tsinghua.stat.mid_term; import j ...

  2. Java for LeetCode 211 Add and Search Word - Data structure design

    Design a data structure that supports the following two operations: void addWord(word)bool search(wo ...

  3. ✡ leetcode 170. Two Sum III - Data structure design 设计two sum模式 --------- java

    Design and implement a TwoSum class. It should support the following operations: add and find. add - ...

  4. LeetCode Two Sum III - Data structure design

    原题链接在这里:https://leetcode.com/problems/two-sum-iii-data-structure-design/ 题目: Design and implement a ...

  5. hdu-5929 Basic Data Structure(双端队列+模拟)

    题目链接: Basic Data Structure Time Limit: 7000/3500 MS (Java/Others)    Memory Limit: 65536/65536 K (Ja ...

  6. LeetCode 笔记27 Two Sum III - Data structure design

    Design and implement a TwoSum class. It should support the following operations: add and find. add - ...

  7. Summary: Trie Data Structure

    Implement a Trie Data Structure, and search() & insert() function: we need to implement both Cla ...

  8. HDU 5929 Basic Data Structure 模拟

    Basic Data Structure Time Limit: 7000/3500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Oth ...

  9. hdu 4217 Data Structure? 树状数组求第K小

    Data Structure? Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

随机推荐

  1. iOS多线程之GCD小记

    iOS多线程之GCD小记 iOS多线程方案简介 从各种资料中了解到,iOS中目前有4套多线程的方案,分别是下列4中: 1.Pthreads 这是一套可以在很多操作系统上通用的多线程API,是基于C语言 ...

  2. 【原】Storm分布式RPC

    5. Storm高级篇 序列化 分布式RPC High level overview LinearDRPCTopologyBuilder Local mode DRPC Remote mode DRP ...

  3. andriod的简单用法2

    1.在Activity中使用menu //创建菜单项 public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this ...

  4. 批量ping主机脚本

    #! /bin/bash for i in `cat test.list`do   host=`echo $i|awk -F"," '{print $1}'`   app_IP=` ...

  5. 纯CSS基于窗口垂直居中

    都是IE8+的 <!DOCTYPE html> <html> <head> <title>基于窗口垂直居中 by 司徒正美</title> ...

  6. hadoop conf中xml文件修改

    core-site.xml <?xml version="1.0"?><?xml-stylesheet type="text/xsl" hre ...

  7. SaltStack 最新版WebUI部署

    saltstack web uiweb平台界面 saltapi项目主页:http://salt-api.readthedocs.org/en/latest/ halite 项目主页:https://g ...

  8. 使用gcc编译gdb调试

    gcc 在linux系统中,默认是没有安装gcc编译器的,可以通过命令 rpm -q | grep gcc 来查看.安装命令为: yum -y install gcc 安装后,编写一个.c结尾的文件. ...

  9. 为什么 JavaScript 中基本数据类型拥有 toString 之类方法?

    在 JavaSctipt 启示录一书中,关于为什么 JS 中基本数据类型可以调用一堆对象方法.大意即指,当原始数据类型(boolean,Number.String)在调用方法时,JS 将会创建对象,以 ...

  10. @Override must override a superclass method 问题解决

    一.问题的由来 最近接手了了一个合作企业的项目,前期不是我司开发的,上周做了几天的技术对接,客户端界面由我负责对接,从svn检出之后,迫不及待的导入到了本地的myeclipse中,谁知立马就出现了那个 ...