[原创]-跳表SkipList的Java实现——仿照ConcurrentSkipListMap思路

>>PS:仅用来学习跳表的原理。

最底层是全量数据,是通过 Node --> Node 进行连接。底层上面的是索引。

 1 Head nodes          Index nodes
 2 +-+    right        +-+                      +-+
 3 |2|---------------->| |--------------------->| |->null
 4 +-+                 +-+                      +-+
 5  | down              |                        |
 6  v                   v                        v
 7 +-+            +-+  +-+       +-+            +-+       +-+
 8 |1|----------->| |->| |------>| |----------->| |------>| |->null
 9 +-+            +-+  +-+       +-+            +-+       +-+
10  v              |    |         |              |         |
11 Nodes  next     v    v         v              v         v
12 +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+
13 | |->|A|->|B|->|C|->|D|->|E|->|F|->|G|->|H|->|I|->|J|->|K|->null
14 +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+
  • 仿照 ConcurrentSkipListMap 的方式;
  • 内部类 NodeIndexHeadIndex;
  • 泛型、支持传入比较器;
  • 整个跳表的操作入口 HeadIndex<V> head 属性;
  • 实现方法:add、remove、search、size;

 

  1 import java.util.Comparator;
  2 import java.util.Objects;
  3 import java.util.Random;
  4 
  5 public class SkipList<V> {
  6 
  7     private final Comparator<? super V> comparator;
  8 
  9     private HeadIndex<V> head;
 10 
 11     private int size;
 12 
 13     private Random random = new Random();
 14 
 15     public SkipList() {
 16         this.comparator = null;
 17         this.init();
 18     }
 19 
 20     @SuppressWarnings("unused")
 21     public SkipList(Comparator<? super V> comparator) {
 22         this.comparator = comparator;
 23         this.init();
 24     }
 25 
 26     private void init() {
 27         Node<V> node = new Node<>(null, null);
 28         this.head = new HeadIndex<>(node, null, null, 1);
 29     }
 30 
 31     /**
 32      * 添加元素
 33      */
 34     public void add(V value) {
 35         if (value == null) {
 36             throw new NullPointerException();
 37         }
 38         Comparator<? super V> cmp = this.comparator;
 39 
 40         Node<V> pre = findPreNode(value, cmp);
 41         Node<V> add = new Node<>(pre.next, value);
 42         pre.next = add;
 43 
 44         int rnd = random.nextInt();
 45         if ((rnd & 0x80000001) == 0) {
 46             int level = 1, max;
 47             while (((rnd >>>= 1) & 1) == 1) {
 48                 level++;
 49             }
 50             HeadIndex<V> h = head;
 51             Index<V> idx = null;
 52             if (level <= (max = head.level)) {
 53                 for (int i = level; i > 0; i--) {
 54                     idx = new Index<>(add, idx, null);
 55                 }
 56             } else {
 57                 level = max + 1;
 58                 @SuppressWarnings("unchecked")
 59                 Index<V>[] idxs = (Index<V>[]) new Index<?>[level + 1];
 60                 for (int i = 1; i <= level; i++) {
 61                     idxs[i] = idx = new Index<>(add, idx, null);
 62                 }
 63                 head = h = new HeadIndex<>(h.node, h, idxs[level], level);
 64                 idx = idxs[level = max];
 65             }
 66 
 67             int insertionLevel = level;
 68             int j = h.level;
 69             Index<V> p = h, r = p.right, t = idx;
 70             while (true) {
 71                 if (t == null) {
 72                     break;
 73                 }
 74                 if (r != null) {
 75                     Node<V> rn = r.node;
 76                     if (compare(cmp, value, rn.value) > 0) {
 77                         p = p.right;
 78                         r = p.right;
 79                         continue;
 80                     }
 81                 }
 82                 if (j == insertionLevel) {
 83                     p.right = t;
 84                     t.right = r;
 85                     if (--insertionLevel == 0) {
 86                         break;
 87                     }
 88                 }
 89                 if (--j >= insertionLevel && j < level) {
 90                     t = t.down;
 91                 }
 92                 p = p.down;
 93                 r = p.right;
 94             }
 95         }
 96 
 97         this.size++;
 98     }
 99 
100     /**
101      * 删除元素
102      * —— 当元素不存在时false。删除成功返回true。
103      */
104     private boolean remove(V value) {
105         Comparator<? super V> cmp = this.comparator;
106         Node<V> pre = findPreNode(value, cmp);
107         Node<V> node = pre.next;
108         if (node == null || !Objects.equals(node.value, value)) {
109             return false;
110         }
111         // 删除索引
112         Index<V> p = head, r = p.right;
113         while (true) {
114             if (r != null) {
115                 Node<V> rn = r.node;
116                 if (compare(cmp, value, rn.value) > 0) {
117                     p = p.right;
118                     r = p.right;
119                     continue;
120                 }
121                 if (rn == node) {
122                     p.right = r.right;
123                 }
124             }
125             if (p.down == null) {
126                 break;
127             }
128             p = p.down;
129             r = p.right;
130         }
131         HeadIndex<V> h = head;
132         if (h.right == null) {
133             if (h.level > 1) {
134                 head = (HeadIndex<V>) head.down;
135             }
136         }
137         // 删除节点
138         pre.next = node.next;
139         this.size--;
140         return true;
141     }
142 
143     /**
144      * 判断指定元素是否存在
145      */
146     public boolean search(V target) {
147         if (target == null) {
148             throw new NullPointerException();
149         }
150         Node<V> node = findPreNode(target, this.comparator);
151         return node.next != null && Objects.equals(node.next.value, target);
152     }
153 
154     public int size() {
155         return this.size;
156     }
157 
158     private Node<V> findPreNode(V target, Comparator<? super V> cmp) {
159         Index<V> p = head, r = p.right;
160         while (true) {
161             if (r != null) {
162                 Node<V> rn = r.node;
163                 if (compare(cmp, target, rn.value) > 0) {
164                     p = p.right;
165                     r = p.right;
166                     continue;
167                 }
168             }
169             if (p.down == null) {
170                 Node<V> node = p.node;
171                 while (node.next != null && compare(cmp, target, node.next.value) > 0) {
172                     node = node.next;
173                 }
174                 return node;
175             }
176             p = p.down;
177             r = p.right;
178         }
179     }
180 
181     @SuppressWarnings({"unchecked", "rawtypes"})
182     private int compare(Comparator c, Object x, Object y) {
183         return (c != null) ? c.compare(x, y) : ((Comparable) x).compareTo(y);
184     }
185 
186     @Override
187     public String toString() {
188         StringBuilder text = new StringBuilder();
189         Node<V> node = head.node.next;
190         while (node != null) {
191             text.append(node.value).append("  ");
192             node = node.next;
193         }
194         return text.toString();
195     }
196 
197     static final class Node<V> {
198         Node<V> next;
199         V value;
200 
201         public Node(Node<V> next, V value) {
202             this.next = next;
203             this.value = value;
204         }
205     }
206 
207     static class Index<V> {
208         Node<V> node;
209         Index<V> down;
210         Index<V> right;
211 
212         public Index(Node<V> node, Index<V> down, Index<V> right) {
213             this.node = node;
214             this.down = down;
215             this.right = right;
216         }
217     }
218 
219     static final class HeadIndex<V> extends Index<V> {
220         int level;
221 
222         public HeadIndex(Node<V> node, Index<V> down, Index<V> right, int level) {
223             super(node, down, right);
224             this.level = level;
225         }
226     }
227 
228     public static void main(String[] args) {
229         System.out.println("----------------------");
230         SkipList<Integer> list = new SkipList<>();
231         list.add(1);
232         list.add(5);
233         list.add(5);
234         list.add(5);
235         list.add(4);
236         list.add(5);
237         list.add(4);
238         list.add(4);
239         list.add(12);
240         list.add(12);
241         list.add(4);
242         list.add(9);
243         list.add(0);
244         list.add(9);
245         list.add(9);
246         list.add(2);
247         list.add(9);
248         list.add(12);
249         list.add(2);
250         System.out.println("Size: " + list.size());
251         System.out.println("----------------------");
252         System.out.println(list.search(4));
253         System.out.println(list.search(3));
254         System.out.println(list.search(0));
255         System.out.println(list.search(8));
256         System.out.println(list.search(9));
257         System.out.println("----------------------");
258         list.add(3);
259         System.out.println(list.search(3));
260         list.remove(3);
261         System.out.println(list.search(3));
262         System.out.println("----------------------");
263         System.out.println(list);
264         System.out.println("----------------------");
265         while (list.remove(12)) {
266             System.out.println(list);
267         }
268         while (list.remove(4)) {
269             System.out.println(list);
270         }
271     }
272 
273 }

 

posted @ 2020-04-25 22:11  夜雨声歇  阅读(141)  评论(0)    收藏  举报