Skip to content

Commit 70d586e

Browse files
author
huzheng
committedSep 3, 2017
SkipList written by java
1 parent 11b8bbe commit 70d586e

File tree

1 file changed

+200
-0
lines changed

1 file changed

+200
-0
lines changed
 

‎template/sort/SkipList.java

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
import org.junit.Assert;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
import java.util.Random;
6+
7+
public class SkipList {
8+
9+
private static class Node {
10+
int value;
11+
Node left, down;
12+
13+
Node(int x) {
14+
this(x, null, null);
15+
}
16+
17+
Node(int x, Node down, Node left) {
18+
this.value = x;
19+
this.down = down;
20+
this.left = left;
21+
}
22+
}
23+
24+
private List<Node> head;
25+
private double p;
26+
private int size;
27+
private Random rand;
28+
29+
public SkipList(double p, int maxHeight) {
30+
this.head = new ArrayList<Node>();
31+
this.p = p;
32+
this.size = 0;
33+
assert maxHeight > 0;
34+
for (int i = 0; i < maxHeight; i++) {
35+
head.add(new Node(0));
36+
if (i > 0) {
37+
head.get(i).down = head.get(i - 1);
38+
}
39+
}
40+
rand = new Random();
41+
}
42+
43+
public SkipList() {
44+
this(0.5, 32);
45+
}
46+
47+
private int randomHeight() {
48+
int h = 0;
49+
while (rand.nextDouble() < p && h < 64)
50+
h++;
51+
return h + 1;
52+
}
53+
54+
public void add(int value) {
55+
final int maxHeight = head.size();
56+
Node[] update = new Node[maxHeight];
57+
Node it = head.get(maxHeight - 1);
58+
int h = maxHeight - 1;
59+
while (it != null) {
60+
if (it.left == null || value < it.left.value) {
61+
update[h--] = it;
62+
it = it.down;
63+
} else {
64+
it = it.left;
65+
}
66+
}
67+
int currentHeight = randomHeight();
68+
Node[] current = new Node[currentHeight];
69+
for (h = 0; h < currentHeight; h++) {
70+
current[h] = new Node(value);
71+
if (h > 0) {
72+
current[h].down = current[h - 1];
73+
}
74+
}
75+
if (maxHeight < currentHeight) {
76+
for (h = maxHeight; h < currentHeight; h++) {
77+
head.add(new Node(0, head.get(h - 1), current[h]));
78+
}
79+
for (h = 0; h < maxHeight; h++) {
80+
current[h].left = update[h].left;
81+
update[h].left = current[h];
82+
}
83+
} else {
84+
for (h = 0; h < currentHeight; h++) {
85+
current[h].left = update[h].left;
86+
update[h].left = current[h];
87+
}
88+
}
89+
size++;
90+
}
91+
92+
public boolean found(int value) {
93+
final int maxHeight = head.size();
94+
Node it = head.get(maxHeight - 1);
95+
while (it != null) {
96+
if (it.left == null || value <= it.left.value) {
97+
if (it.left != null && it.left.value == value) return true;
98+
it = it.down;
99+
} else {
100+
it = it.left;
101+
}
102+
}
103+
return false;
104+
}
105+
106+
public boolean remove(int value) {
107+
final int maxHeight = head.size();
108+
Node it = head.get(maxHeight - 1);
109+
boolean isFound = false;
110+
while (it != null) {
111+
if (it.left == null || value <= it.left.value) {
112+
if (it.left != null && it.left.value == value) {
113+
// do the removing
114+
isFound = true;
115+
it.left = it.left.left;
116+
}
117+
it = it.down;
118+
} else {
119+
it = it.left;
120+
}
121+
}
122+
if (isFound) {
123+
for (int i = head.size() - 1; i >= 1; i--) {
124+
if (head.get(i).left == null) {
125+
head.remove(i);
126+
}
127+
}
128+
--size;
129+
}
130+
return isFound;
131+
}
132+
133+
public int[] toArrays() {
134+
int i = 0;
135+
int[] values = new int[size];
136+
for (Node it = head.get(0).left; it != null; it = it.left) {
137+
values[i++] = it.value;
138+
}
139+
return values;
140+
}
141+
142+
public int size() {
143+
return size;
144+
}
145+
146+
public void print() {
147+
for (int i = head.size() - 1; i >= 0; i--) {
148+
Node it = head.get(i).left;
149+
System.out.print("Height #" + i + ": ");
150+
while (it != null) {
151+
System.out.print(it.value + " ");
152+
it = it.left;
153+
}
154+
System.out.println();
155+
156+
}
157+
}
158+
159+
public static void main(String args[]) {
160+
SkipList skipList = new SkipList();
161+
int[] values1 = new int[] { 23, 12, 33, 45, 8, 1, 48, 49, 32, 24, 0, 88 };
162+
int[] result1 = new int[] { 0, 1, 8, 12, 23, 24, 32, 33, 45, 48, 49, 88 };
163+
for (int i = 0; i < values1.length; i++) {
164+
skipList.add(values1[i]);
165+
}
166+
skipList.print();
167+
168+
Assert.assertEquals(skipList.size(), result1.length);
169+
Assert.assertArrayEquals(result1, skipList.toArrays());
170+
171+
Assert.assertTrue(skipList.remove(0));
172+
Assert.assertEquals(skipList.size(), result1.length - 1);
173+
Assert.assertArrayEquals(new int[] { 1, 8, 12, 23, 24, 32, 33, 45, 48, 49, 88 },
174+
skipList.toArrays());
175+
176+
Assert.assertFalse(skipList.remove(0));
177+
Assert.assertEquals(skipList.size(), result1.length - 1);
178+
Assert.assertArrayEquals(new int[] { 1, 8, 12, 23, 24, 32, 33, 45, 48, 49, 88 },
179+
skipList.toArrays());
180+
181+
Assert.assertTrue(skipList.remove(88));
182+
Assert.assertEquals(skipList.size(), result1.length - 2);
183+
Assert.assertArrayEquals(new int[] { 1, 8, 12, 23, 24, 32, 33, 45, 48, 49 },
184+
skipList.toArrays());
185+
186+
Assert.assertTrue(skipList.remove(33));
187+
Assert.assertEquals(skipList.size(), result1.length - 3);
188+
Assert.assertArrayEquals(new int[] { 1, 8, 12, 23, 24, 32, 45, 48, 49 }, skipList.toArrays());
189+
190+
Assert.assertTrue(skipList.remove(12));
191+
Assert.assertEquals(skipList.size(), result1.length - 4);
192+
Assert.assertArrayEquals(new int[] { 1, 8, 23, 24, 32, 45, 48, 49 }, skipList.toArrays());
193+
194+
for (int value : skipList.toArrays()) {
195+
Assert.assertTrue(skipList.remove(value));
196+
}
197+
Assert.assertTrue(skipList.size() == 0);
198+
}
199+
}
200+

0 commit comments

Comments
 (0)
Please sign in to comment.