实现语言为java
package com.github.ralgond.yousuggest;
import java.util.Iterator;
import java.util.Random;
public class SkipListSet<E extends Comparable<? super E>> implements Iterable<E> {
private class Node {
public E data;
public Object nextArray[];
public Node(E data, int level) {
this.data = data;
nextArray = new Object[level];
}
public Node next(int level) {
return (Node)nextArray[level];
}
public void setNext(int level, Node n) {
nextArray[level] = n;
}
public int level() {
return nextArray.length;
}
}
private final static int MAX_LEVEL = 10;
private Node head;
private Object[] prevArray;
private Random rand = new Random(1);
private int count = 0;
public SkipListSet() {
head = new Node(null, MAX_LEVEL);
prevArray = new Object[MAX_LEVEL];
}
private Node getPrev(int level) {
return (Node)prevArray[level];
}
private void setPrev(int level, Node n) {
prevArray[level] = n;
}
protected boolean findAndRecordPrev(E e) {
for (int i = 0; i < MAX_LEVEL; i++) {
prevArray[i] = head;
}
int level = head.level() - 1;
Node curr = head;
while (level >= 0) {
while (curr.next(level) != null && curr.next(level).data.compareTo(e) < 0) {
curr = curr.next(level);
}
setPrev(level, curr);
level--;
}
if (getPrev(0).next(0) == null)
return false;
return getPrev(0).next(0).data.equals(e);
}
public boolean contains(E e) {
return findAndRecordPrev(e);
}
protected int randomLevel() {
int l = 1;
while (rand.nextInt()%2 == 1) {
l++;
}
l = l < MAX_LEVEL? l : MAX_LEVEL;
return l;
}
public void add(E e) {
boolean found = findAndRecordPrev(e);
if (found)
return;
int randLevel = randomLevel();
Node n = new Node(e, randLevel);
for (int l = 0; l < randLevel; l++) {
n.setNext(l, getPrev(l).next(l));
getPrev(l).setNext(l, n);
}
count++;
}
public void remove(E e) {
boolean found = findAndRecordPrev(e);
if (!found)
return;
Node n = getPrev(0).next(0);
assert(n.data.equals(e));
int level = n.level();
for (int l = 0; l < level; l++) {
getPrev(l).setNext(l, n.next(l));
}
count--;
}
public Iterator<E> iterator() {
return new Iterator<E>() {
Node curr = head.next(0);
public boolean hasNext() {
return curr != null;
}
public E next() {
Node ret = curr;
curr = curr.next(0);
return ret.data;
}
};
}
public int size() {
return count;
}
public void clear() {
for (int i = 0; i < head.level(); i++) {
head.setNext(i, null);
}
count = 0;
}
}
单元测试
package com.github.ralgond.yousuggest;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.util.Iterator;
import org.junit.Test;
public class SkipListSetTest {
public void assertEquals2(Iterator<Integer> it, int... ints) {
for (int i = 0;i < ints.length; i++) {
int j = ints[i];
assertEquals((Integer)j, it.next());
}
assertFalse(it.hasNext());
}
@Test
public void test0() {
int a[][] = {
{6,7,8,9},
{6,7,9,8},
{6,8,7,9},
{6,8,9,7},
{6,9,8,7},
{6,9,7,8},
{7,6,8,9},
{7,6,9,8},
{7,8,6,9},
{7,8,9,6},
{7,9,8,6},
{7,9,6,8},
{8,7,6,9},
{8,7,9,6},
{8,6,7,9},
{8,6,9,7},
{8,9,6,7},
{8,9,7,6},
{9,7,8,6},
{9,7,6,8},
{9,8,7,6},
{9,8,6,7},
{9,6,8,7},
{9,6,7,8}
};
SkipListSet<Integer> set = new SkipListSet<>();
for (int i = 0; i < a.length; i++) {
int[] b = a[i];
for (int j = 0; j < b.length; j++) {
set.add(b[j]);
}
assertEquals2(set.iterator(), 6,7,8,9);
assertEquals(4, set.size());
for (int j = 0; j < b.length; j++) {
set.remove(b[j]);
}
assertEquals(0, set.size());
assertFalse(set.iterator().hasNext());
}
}
@Test
public void testRemove1() {
SkipListSet<Integer> set = new SkipListSet<>();
set.add(6);
set.add(9);
set.add(8);
set.add(7);
set.remove(7);
assertEquals2(set.iterator(), 6,8,9);
}
@Test
public void testRemove2() {
SkipListSet<Integer> set = new SkipListSet<>();
set.add(6);
set.add(9);
set.add(8);
set.add(7);
set.remove(7);
set.remove(8);
assertEquals2(set.iterator(), 6,9);
}
@Test
public void testRemove3() {
SkipListSet<Integer> set = new SkipListSet<>();
set.add(6);
set.add(9);
set.add(8);
set.add(7);
set.remove(7);
set.remove(8);
set.remove(9);
assertEquals2(set.iterator(), 6);
}
@Test
public void testRemove4() {
SkipListSet<Integer> set = new SkipListSet<>();
set.add(6);
set.add(9);
set.add(8);
set.add(7);
set.remove(6);
set.remove(7);
set.remove(8);
set.remove(9);
assertFalse(set.iterator().hasNext());
}
@Test
public void testRemoveAndAdd1() {
SkipListSet<Integer> set = new SkipListSet<>();
set.add(6);
set.add(9);
set.add(8);
set.add(7);
set.remove(6);
set.add(6);
assertEquals2(set.iterator(), 6,7,8,9);
}
@Test
public void testRemoveAndAdd2() {
SkipListSet<Integer> set = new SkipListSet<>();
set.add(6);
set.add(9);
set.add(8);
set.add(7);
set.remove(7);
set.add(7);
assertEquals2(set.iterator(), 6,7,8,9);
}
@Test
public void testRemoveAndAdd3() {
SkipListSet<Integer> set = new SkipListSet<>();
set.add(6);
set.add(9);
set.add(8);
set.add(7);
set.remove(6);
set.remove(7);
set.remove(8);
set.remove(9);
set.add(6);
set.add(9);
set.add(8);
set.add(7);
assertEquals2(set.iterator(), 6,7,8,9);
}
@Test
public void testContains() {
SkipListSet<Integer> set = new SkipListSet<>();
set.add(6);
set.add(9);
set.add(8);
set.add(7);
assertTrue(set.contains(6));
assertTrue(set.contains(7));
assertTrue(set.contains(8));
assertTrue(set.contains(9));
assertFalse(set.contains(0));
}
@Test
public void testClear() {
SkipListSet<Integer> set = new SkipListSet<>();
set.add(6);
set.add(9);
set.add(8);
set.add(7);
set.clear();
assertEquals(0, set.size());
assertFalse(set.contains(6));
assertFalse(set.contains(7));
assertFalse(set.contains(8));
assertFalse(set.contains(9));
}
@Test
public void testDup() {
SkipListSet<Integer> set = new SkipListSet<>();
set.add(6);
set.add(9);
set.add(8);
set.add(7);
set.add(6);
set.add(9);
set.add(8);
set.add(7);
assertEquals2(set.iterator(), 6,7,8,9);
assertEquals(4, set.size());
}
}