@@ -66,7 +66,9 @@ skiplist.search(1); // 返回 false,1 已被擦除
66
66
67
67
<!-- 这里可写通用的实现逻辑 -->
68
68
69
- 因为节点 ` level ` 随机,所以需要多个 ` next ` 指针,其余操作类似单链表
69
+ ** 方法一:数据结构**
70
+
71
+ 因为节点 ` level ` 随机,所以需要多个 ` next ` 指针,其余操作类似单链表。
70
72
71
73
<!-- tabs:start -->
72
74
@@ -76,54 +78,56 @@ skiplist.search(1); // 返回 false,1 已被擦除
76
78
77
79
``` python
78
80
class Node :
81
+ __slots__ = [' val' , ' next' ]
82
+
79
83
def __init__ (self , val : int , level : int ):
80
84
self .val = val
81
- self .next = [None for _ in range ( level)]
85
+ self .next = [None ] * level
82
86
83
87
84
88
class Skiplist :
85
- max_level = 16
86
- p = 0.5
89
+ max_level = 32
90
+ p = 0.25
87
91
88
92
def __init__ (self ):
89
93
self .head = Node(- 1 , self .max_level)
90
- self .level = 1
94
+ self .level = 0
91
95
92
96
def search (self , target : int ) -> bool :
93
- p = self .head
97
+ curr = self .head
94
98
for i in range (self .level - 1 , - 1 , - 1 ):
95
- p = self .find_closest(p , i, target)
96
- if p .next[i] != None and p .next[i].val == target:
99
+ curr = self .find_closest(curr , i, target)
100
+ if curr .next[i] and curr .next[i].val == target:
97
101
return True
98
102
return False
99
103
100
104
def add (self , num : int ) -> None :
105
+ curr = self .head
101
106
level = self .random_level()
102
- self .level = max (self .level, level)
103
107
node = Node(num, level)
104
- p = self .head
108
+ self .level = max ( self .level, level)
105
109
for i in range (self .level - 1 , - 1 , - 1 ):
106
- p = self .find_closest(p , i, num)
110
+ curr = self .find_closest(curr , i, num)
107
111
if i < level:
108
- node.next[i] = p .next[i]
109
- p .next[i] = node
112
+ node.next[i] = curr .next[i]
113
+ curr .next[i] = node
110
114
111
115
def erase (self , num : int ) -> bool :
116
+ curr = self .head
112
117
ok = False
113
- p = self .head
114
118
for i in range (self .level - 1 , - 1 , - 1 ):
115
- p = self .find_closest(p , i, num)
116
- if p .next[i] != None and p .next[i].val == num:
117
- p .next[i] = p .next[i].next[i]
119
+ curr = self .find_closest(curr , i, num)
120
+ if curr .next[i] and curr .next[i].val == num:
121
+ curr .next[i] = curr .next[i].next[i]
118
122
ok = True
119
- while self .level > 1 and self .head.next[self .level - 1 ] == None :
123
+ while self .level > 1 and self .head.next[self .level - 1 ] is None :
120
124
self .level -= 1
121
125
return ok
122
126
123
- def find_closest (self , p : Node, level : int , target : int ) -> Node:
124
- while p .next[level] != None and p .next[level].val < target:
125
- p = p .next[level]
126
- return p
127
+ def find_closest (self , curr : Node, level : int , target : int ) -> Node:
128
+ while curr .next[level] and curr .next[level].val < target:
129
+ curr = curr .next[level]
130
+ return curr
127
131
128
132
def random_level (self ) -> int :
129
133
level = 1
@@ -145,84 +149,90 @@ class Skiplist:
145
149
146
150
``` java
147
151
class Skiplist {
148
-
149
- private static final int DEFAULT_MAX_LEVEL = 16 ;
150
- private static final double DEFAULT_P_FACTOR = 0.5 ;
151
-
152
- private final Node head;
153
- private int currentLevel;
152
+ private static final int MAX_LEVEL = 32 ;
153
+ private static final double P = 0.25 ;
154
+ private static final Random RANDOM = new Random ();
155
+ private final Node head = new Node (- 1 , MAX_LEVEL );
156
+ private int level = 0 ;
154
157
155
158
public Skiplist () {
156
- this . head = new Node (0 , DEFAULT_MAX_LEVEL );
157
- this . currentLevel = 1 ;
159
+
158
160
}
159
161
160
162
public boolean search (int target ) {
161
- Node node = head;
162
- for (int i = currentLevel - 1 ; i >= 0 ; i -- ) {
163
- node = findClosest(node , i, target);
164
- if (node . next[i] != null && node . next[i]. value == target) {
165
- return true ;
166
- }
167
- }
168
- return false ;
163
+ Node curr = head;
164
+ for (int i = level - 1 ; i >= 0 ; -- i ) {
165
+ curr = findClosest(curr , i, target);
166
+ if (curr . next[i] != null && curr . next[i]. val == target) {
167
+ return true ;
168
+ }
169
+ }
170
+ return false ;
169
171
}
170
172
171
173
public void add (int num ) {
172
- int level = randomLevel() ;
173
- currentLevel = Math . max(currentLevel, level );
174
- Node newNode = new Node (num, level );
175
- Node updateNode = head ;
176
- for (int i = currentLevel - 1 ; i >= 0 ; i -- ) {
177
- updateNode = findClosest(updateNode , i, num);
178
- if (i < level ) {
179
- newNode . next[i] = updateNode . next[i];
180
- updateNode . next[i] = newNode ;
181
- }
182
- }
174
+ Node curr = head ;
175
+ int lv = randomLevel( );
176
+ Node node = new Node (num, lv );
177
+ level = Math . max(level, lv) ;
178
+ for (int i = level - 1 ; i >= 0 ; -- i ) {
179
+ curr = findClosest(curr , i, num);
180
+ if (i < lv ) {
181
+ node . next[i] = curr . next[i];
182
+ curr . next[i] = node ;
183
+ }
184
+ }
183
185
}
184
186
185
187
public boolean erase (int num ) {
186
- boolean exist = false ;
187
- Node node = head ;
188
- for (int i = currentLevel - 1 ; i >= 0 ; i -- ) {
189
- node = findClosest(node , i, num);
190
- if (node . next[i] != null && node . next[i]. value == num) {
191
- node . next[i] = node . next[i]. next[i];
192
- exist = true ;
193
- }
194
- }
195
- while (currentLevel > 1 && head. next[currentLevel - 1 ] == null ) {
196
- currentLevel -- ;
197
- }
198
- return exist ;
188
+ Node curr = head ;
189
+ boolean ok = false ;
190
+ for (int i = level - 1 ; i >= 0 ; -- i ) {
191
+ curr = findClosest(curr , i, num);
192
+ if (curr . next[i] != null && curr . next[i]. val == num) {
193
+ curr . next[i] = curr . next[i]. next[i];
194
+ ok = true ;
195
+ }
196
+ }
197
+ while (level > 1 && head. next[level - 1 ] == null ) {
198
+ -- level ;
199
+ }
200
+ return ok ;
199
201
}
200
202
201
- private Node findClosest (Node node , int level , int value ) {
202
- while (node . next[level] != null && node . next[level]. value < value ) {
203
- node = node . next[level];
204
- }
205
- return node ;
203
+ private Node findClosest (Node curr , int level , int target ) {
204
+ while (curr . next[level] != null && curr . next[level]. val < target ) {
205
+ curr = curr . next[level];
206
+ }
207
+ return curr ;
206
208
}
207
209
208
- private int randomLevel () {
209
- int level = 1 ;
210
- while (level < DEFAULT_MAX_LEVEL && Math . random () < DEFAULT_P_FACTOR ) {
211
- level ++ ;
212
- }
213
- return level;
210
+ private static int randomLevel () {
211
+ int level = 1 ;
212
+ while (level < MAX_LEVEL && RANDOM . nextDouble () < P ) {
213
+ ++ level ;
214
+ }
215
+ return level;
214
216
}
215
217
216
218
static class Node {
217
- int value ;
218
- Node [] next;
219
+ int val ;
220
+ Node [] next;
219
221
220
- Node (int value , int level ) {
221
- this . value = value ;
222
- this . next = new Node [level];
223
- }
222
+ Node (int val , int level ) {
223
+ this . val = val ;
224
+ next = new Node [level];
225
+ }
224
226
}
225
227
}
228
+
229
+ /**
230
+ * Your Skiplist object will be instantiated and called as such:
231
+ * Skiplist obj = new Skiplist();
232
+ * boolean param_1 = obj.search(target);
233
+ * obj.add(num);
234
+ * boolean param_3 = obj.erase(num);
235
+ */
226
236
```
227
237
228
238
### ** Go**
@@ -326,6 +336,90 @@ func randomLevel() int {
326
336
*/
327
337
```
328
338
339
+ ### ** C++**
340
+
341
+ ``` cpp
342
+ struct Node {
343
+ int val;
344
+ vector<Node* > next;
345
+ Node(int v, int level) : val(v), next(level, nullptr) {}
346
+ };
347
+
348
+ class Skiplist {
349
+ public:
350
+ const int p = RAND_MAX / 4;
351
+ const int maxLevel = 32;
352
+ Node* head;
353
+ int level;
354
+
355
+ Skiplist() {
356
+ head = new Node(-1, maxLevel);
357
+ level = 0;
358
+ }
359
+
360
+ bool search (int target) {
361
+ Node* curr = head;
362
+ for (int i = level - 1; ~ i; --i)
363
+ {
364
+ curr = findClosest(curr, i, target);
365
+ if (curr->next[ i] && curr->next[ i] ->val == target) return true;
366
+ }
367
+ return false;
368
+ }
369
+
370
+ void add(int num) {
371
+ Node* curr = head;
372
+ int lv = randomLevel();
373
+ Node* node = new Node(num, lv);
374
+ level = max(level, lv);
375
+ for (int i = level - 1; ~ i; --i)
376
+ {
377
+ curr = findClosest(curr, i, num);
378
+ if (i < lv)
379
+ {
380
+ node->next[ i] = curr->next[ i] ;
381
+ curr->next[ i] = node;
382
+ }
383
+ }
384
+ }
385
+
386
+ bool erase(int num) {
387
+ Node* curr = head;
388
+ bool ok = false;
389
+ for (int i = level - 1; ~ i; --i)
390
+ {
391
+ curr = findClosest(curr, i, num);
392
+ if (curr->next[ i] && curr->next[ i] ->val == num)
393
+ {
394
+ curr->next[ i] = curr->next[ i] ->next[ i] ;
395
+ ok = true;
396
+ }
397
+ }
398
+ while (level > 1 && !head->next[ level - 1] ) --level;
399
+ return ok;
400
+ }
401
+
402
+ Node* findClosest(Node* curr, int level, int target) {
403
+ while (curr->next[level] && curr->next[level]->val < target) curr = curr->next[level];
404
+ return curr;
405
+ }
406
+
407
+ int randomLevel() {
408
+ int lv = 1;
409
+ while (lv < maxLevel && rand() < p) ++lv;
410
+ return lv;
411
+ }
412
+ };
413
+
414
+ /**
415
+ * Your Skiplist object will be instantiated and called as such:
416
+ * Skiplist* obj = new Skiplist();
417
+ * bool param_1 = obj->search(target);
418
+ * obj->add(num);
419
+ * bool param_3 = obj->erase(num);
420
+ * /
421
+ ```
422
+
329
423
### **...**
330
424
331
425
```
0 commit comments