Add Makefile, update readme and fix valgrind found leaks
This commit is contained in:
parent
57e0a96f18
commit
526617cfc9
3 changed files with 69 additions and 2 deletions
25
Makefile
Normal file
25
Makefile
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
DEBUG?= -g
|
||||||
|
CFLAGS?= -O2 -Wall -W -DSDS_ABORT_ON_OOM
|
||||||
|
CCOPT= $(CFLAGS)
|
||||||
|
|
||||||
|
OBJ = main.o skiplist.o x.o
|
||||||
|
PRGNAME = sl
|
||||||
|
|
||||||
|
all: sl
|
||||||
|
|
||||||
|
# Deps (use make dep to generate this)
|
||||||
|
main.o: x.h skiplist.h x.c skiplist.c main.c
|
||||||
|
x.o: x.c x.h
|
||||||
|
skiplist.o: x.c x.h skiplist.c skiplist.h
|
||||||
|
|
||||||
|
sl: $(OBJ)
|
||||||
|
$(CC) -o $(PRGNAME) $(CCOPT) $(DEBUG) $(OBJ)
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(CC) -c $(CCOPT) $(DEBUG) $(COMPILE_TIME) $<
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(PRGNAME) *.o
|
||||||
|
|
||||||
|
dep:
|
||||||
|
$(CC) -MM *.c
|
|
@ -2,3 +2,10 @@ skiplist
|
||||||
=========
|
=========
|
||||||
|
|
||||||
Academic example of skip list implementation in C.
|
Academic example of skip list implementation in C.
|
||||||
|
|
||||||
|
To compile just run
|
||||||
|
|
||||||
|
.. code:: bash
|
||||||
|
|
||||||
|
make
|
||||||
|
|
||||||
|
|
39
skiplist.c
39
skiplist.c
|
@ -114,6 +114,11 @@ void sl_print(const slist *sl)
|
||||||
#define HEAD 1
|
#define HEAD 1
|
||||||
#define TAIL 0
|
#define TAIL 0
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Repeatedly toss a coin until we get tails.
|
||||||
|
* Denote with i the number of times coin came up heads
|
||||||
|
* and return it.
|
||||||
|
*/
|
||||||
int _toss_coin(int maxlevel) {
|
int _toss_coin(int maxlevel) {
|
||||||
int i;
|
int i;
|
||||||
int x;
|
int x;
|
||||||
|
@ -135,14 +140,14 @@ int _toss_coin(int maxlevel) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clean top levels with only INFINITY nodes until only one such
|
* Remove top levels with only INFINITY nodes until only one such
|
||||||
* level exists.
|
* level exists.
|
||||||
*/
|
*/
|
||||||
void _sl_clean_top(slist *sl)
|
void _sl_clean_top(slist *sl)
|
||||||
{
|
{
|
||||||
sl_node *foo;
|
sl_node *foo;
|
||||||
|
|
||||||
for (foo = sl->topleft; foo->below != NULL; foo = foo->below) {
|
for (foo = sl->topleft; foo->below != NULL;) {
|
||||||
if (foo->next->key == KEY_INF_MAX
|
if (foo->next->key == KEY_INF_MAX
|
||||||
&& foo->below->next->key == KEY_INF_MAX) {
|
&& foo->below->next->key == KEY_INF_MAX) {
|
||||||
sl->topleft = foo->below;
|
sl->topleft = foo->below;
|
||||||
|
@ -150,14 +155,28 @@ void _sl_clean_top(slist *sl)
|
||||||
sl->topleft->above = NULL;
|
sl->topleft->above = NULL;
|
||||||
sl->topright->above = NULL;
|
sl->topright->above = NULL;
|
||||||
--sl->maxlevel;
|
--sl->maxlevel;
|
||||||
|
|
||||||
free(foo->data);
|
free(foo->data);
|
||||||
free(foo->next);
|
free(foo->next);
|
||||||
free(foo);
|
free(foo);
|
||||||
|
|
||||||
|
foo = sl->topleft;
|
||||||
debug("cleaned one level\n");
|
debug("cleaned one level\n");
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Toss coin and get i.
|
||||||
|
* If i is greather than or equal to skip list max level then
|
||||||
|
* add one more level.
|
||||||
|
* Search for x and find the positions of the items with largest key
|
||||||
|
* less than x.
|
||||||
|
* Insert item into each level up to i.
|
||||||
|
* If key is found then just update its data.
|
||||||
|
*/
|
||||||
int sl_add(slist *sl, int key, void *data)
|
int sl_add(slist *sl, int key, void *data)
|
||||||
{
|
{
|
||||||
sl_node *foo;
|
sl_node *foo;
|
||||||
|
@ -190,6 +209,9 @@ int sl_add(slist *sl, int key, void *data)
|
||||||
if (foo->below == NULL) {
|
if (foo->below == NULL) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* Save nodes that will be updated with new node.
|
||||||
|
*/
|
||||||
update[level--] = foo;
|
update[level--] = foo;
|
||||||
foo = foo->below;
|
foo = foo->below;
|
||||||
}
|
}
|
||||||
|
@ -233,6 +255,14 @@ int sl_add(slist *sl, int key, void *data)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Start at the top left position.
|
||||||
|
* At the current position compare key with node's key.
|
||||||
|
* If key is found then return it.
|
||||||
|
* If key > node's key then scan forward.
|
||||||
|
* If key < node's key then drop down.
|
||||||
|
* If we drop down past the bottom list then return NULL.
|
||||||
|
*/
|
||||||
sl_node *sl_find(slist *sl, int key)
|
sl_node *sl_find(slist *sl, int key)
|
||||||
{
|
{
|
||||||
sl_node *foo;
|
sl_node *foo;
|
||||||
|
@ -254,6 +284,11 @@ sl_node *sl_find(slist *sl, int key)
|
||||||
return foo;
|
return foo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Search for key and find positions with the key.
|
||||||
|
* Remove found positions.
|
||||||
|
* Remove all but one list containing only INFINITY keys.
|
||||||
|
*/
|
||||||
int sl_remove(slist *sl, int key)
|
int sl_remove(slist *sl, int key)
|
||||||
{
|
{
|
||||||
sl_node *foo;
|
sl_node *foo;
|
||||||
|
|
Loading…
Reference in a new issue