2
* ===========================================================================
5
* National Center for Biotechnology Information
7
* This software/database is a "United States Government Work" under the
8
* terms of the United States Copyright Act. It was written as part of
9
* the author's official duties as a United States Government employee and
10
* thus cannot be copyrighted. This software/database is freely available
11
* to the public for use. The National Library of Medicine and the U.S.
12
* Government have not placed any restriction on its use or reproduction.
14
* Although all reasonable efforts have been taken to ensure the accuracy
15
* and reliability of the software and data, the NLM and the U.S.
16
* Government do not and cannot warrant the performance or results that
17
* may be obtained by using this software or data. The NLM and the U.S.
18
* Government disclaim all warranties, express or implied, including
19
* warranties of performance, merchantability or fitness for any particular
22
* Please cite the author in any work or product based on this material.
24
* ===========================================================================
28
* Author: Kun-Mao Chao and Jinghui Zhang
30
* Version Creation Date: 5/24/95
35
* Example of Skip List source code for C:
37
* Skip Lists are a probabilistic alternative to balanced trees, as
38
* described in the June 1990 issue of CACM and were invented by
39
* William Pugh in 1987.
41
* This file contains source code to implement a dictionary using
42
* skip lists and a test driver to test the routines.
44
* A couple of comments about this implementation:
45
* The routine randomLevel has been hard-coded to generate random
46
* levels using p=0.25. It can be easily changed.
48
* The insertion routine has been implemented so as to use the
49
* dirty hack described in the CACM paper: if a random level is
50
* generated that is more than the current maximum level, the
51
* current maximum level plus one is used instead.
53
* Levels start at zero and go up to MaxLevel (which is equal to
54
* (MaxNumberOfLevels-1).
56
* The compile flag allowDuplicates determines whether or not duplicates
57
* are allowed. If defined, duplicates are allowed and act in a FIFO manner.
58
* If not defined, an insertion of a value already in the file updates the
59
* previously existing binding.
61
* BitsInRandom is defined to be the number of bits returned by a call to
62
* random(). For most all machines with 32-bit integers, this is 31 bits
67
* --------------------------------------------------------------------------
68
* Date Name Description of modification
71
* Revision 6.1 1998/08/24 21:19:39 kans
72
* fixed -v -fd warnings
74
* Revision 6.0 1997/08/25 18:54:42 madden
75
* Revision changed to 6.0
77
* Revision 5.0 1996/05/28 13:43:15 ostell
80
* Revision 4.1 1996/05/21 13:43:39 epstein
81
* change function-name 'delete' because it conflicts with VMS
83
* Revision 4.0 1995/07/26 13:50:15 ostell
84
* force revision to 4.0
86
* Revision 1.2 1995/05/25 20:22:28 zjing
91
* ==========================================================================
104
/* init - defines NIL1 and initializes the random bit source */
107
NIL1 = newNodeOfLevel(0);
108
NIL1->key = 0x7fffffff;
110
NIL1->forward[0] = NIL1;
112
randomsLeft = BitsInRandom/2;
115
/* list_NIL_free - free NIL1 1/27/94 */
116
void list_NIL_free(void) {
120
/* newList - create a new list */
125
l = (list)ckalloc(sizeof(struct listStructure));
127
l->header = newNodeOfLevel(MaxNumberOfLevels);
129
l->header->value = NULL;
130
for(i=0;i<MaxNumberOfLevels;i++) l->header->forward[i] = NIL1;
134
/* unewList - create a new list */
135
ulist unewList(void) {
138
l = (ulist)ckalloc(sizeof(struct ulistStructure));
139
l->header = (unode)ckalloc(sizeof(struct unodeStructure));
141
l->header->link = NULL;
145
/* reset_pos - reset cur_p */
146
void reset_pos(list l)
152
for (k = 0; k <= l->level; ++k) l->update[k] = p;
155
/* sreset_pos - reset l->update[0] */
156
void sreset_pos(list l)
158
l->update[0] = l->header;
161
/* freeList - free the space of the list */
162
void freeList(list l)
166
void decre(fragment PNTR);
180
/* ufreeList - free the space of the ulist */
181
void ufreeList(ulist l)
196
/* randomLevel - return a random level */
197
Int4 randomLevel(Int4 maxl)
198
{register Int4 level = 0;
204
if (--randomsLeft == 0) {
206
randomsLeft = BitsInRandom/2;
209
return(level>maxl ? maxl : level);
212
/* uinsert - insert a new node to the ulist */
213
void uinsert(ulist l, keyType key)
217
for (p=l->header,q=p->link; q && q->key<key; p=q, q=p->link) continue;
218
q = (unode)ckalloc(sizeof(struct unodeStructure));
224
/* delete_by_key - delete a node from the list by key */
225
Int4 delete_by_key(list l, keyType key)
233
while (q = p->forward[k], q->key < key) p = q;
238
for(k=0; k<=m && (p=l->update[k])->forward[k] == q; k++)
239
p->forward[k] = q->forward[k];
241
while( l->header->forward[m] == NIL1 && m > 0 )
249
/* usearch - search a node in the ulist by key */
250
Boolean usearch(ulist l, keyType key)
254
if (!l) return(false);
255
for (p=l->header; p && p->key < key; p=p->link) continue;
256
if (p && p->key == key) return(true);
260
/* rsearch - search a node in the list by key */
261
/* find p s.t. p->key < key <= (p->forward[0])->key */
262
valueType rsearch(list l, keyType key)
269
while (q = p->forward[k], q->key < key) p = q;
275
/* rsearch_next - search from cur_p */
276
/* find p s.t. p->key < key <= (p->forward[0])->key */
277
valueType rsearch_next(list l, keyType key)
284
while (q = p->forward[k] , q->key < key) p = q;
290
/* cur_key - return the key of the node pointed by the pointer cur_p */
291
keyType cur_key(list l)
293
return((l->update[0])->key);
296
/* update_node - update the value of the node pointed by cur_p */
297
void update_node(list l, valueType value)
299
(l->update[0])->value = value;
302
/* next_key - return the key of the node next to the node pointed by cur_p */
303
keyType next_key(list l)
307
p = (l->update[0])->forward[0];
308
if (p != NIL1) return(p->key);
312
/* next_val - return the value of the node next to the node pointed by cur_p */
313
valueType next_val(list l)
317
p = (l->update[0])->forward[0];
318
if (p != NIL1) return(p->value);
322
/* next - move l->cur_p right */
330
if (q == NIL1) return;
332
for (k = 0; k <= l->level && (((l->update[k])->forward[k])
333
== q); k++) l->update[k] = q;
337
/* snext - move l->update[0] right */
338
valueType snext(list l)
348
/*delete_next - delete the node next to the node pointed by cur_p */
349
void delete_next(list l)
355
q = (l->update[0])->forward[0];
356
if (q == NIL1) return;
357
for (k=0; k<=m && (p=l->update[k])->forward[k] == q; k++)
358
p->forward[k] = q->forward[k];
360
while (l->header->forward[m] == NIL1 && m > 0) m--;
364
/* insert_next - insert a new node next to the node pointed by cur_p */
365
void insert_next(list l, keyType key, valueType value)
370
k = randomLevel(MaxLevel);
373
l->update[k] = l->header;
375
q = newNodeOfLevel(k);
380
q->forward[k] = p->forward[k];