/* From tdk@dcn.davis.ca.us Wed Oct 25 14:33:55 1995 Date: Wed, 25 Oct 1995 14:33:42 -0700 Subject: SkipList Code From: Ted Krovetz To: "Phil Rogaway" Here's my simple C++ implementation of SkipLists. My version that uses templates isn't working correctly, so this one will have to do. Besides the algorithm, the only interesting thing in the program is the overloading of new and delete. I do this to create a variably sized struct. -Ted PS -- Almost no comments in the code. Sorry. */ //***************************************************** // // skiplist.h -- by Ted Krovetz (9/25/94) // //***************************************************** typedef int datatype; //***************************************************** const int maxlevel = 16; const int pratio = 4; //***************************************************** class listnode; // Forward declaration //***************************************************** class skiplist { private: listnode *head; public: skiplist(); ~skiplist(); int search(datatype data); void insert(datatype data); void remove(datatype data); }; //***************************************************** //***************************************************** // // skiplist.cp -- by Ted Krovetz (9/25/94) // //***************************************************** #include #include #include "sl.h" //***************************************************** typedef class listnode *listnodeptr; //***************************************************** class listnode { private: datatype data; listnodeptr nextnode[1]; public: void* operator new(size_t size, int numptrs) { return malloc(size + (numptrs-1) * sizeof(listnodeptr)); } void operator delete(void* ptr) { free(ptr); } datatype getdata() { return data; } void setdata(datatype newdata) { data = newdata; } listnodeptr getnextnode(int i) { return nextnode[i]; } void setnextnode(int i, listnodeptr n) { nextnode[i] = n; } }; //***************************************************** int randomlevel() { int lvl = 1; while (rand() < (RAND_MAX / pratio)) lvl++; return (lvl <= maxlevel ? lvl : maxlevel); } //***************************************************** skiplist::skiplist() { head = new(maxlevel) listnode; for (int i=0;isetnextnode(i, NULL); srand((unsigned int)time(NULL)); } //***************************************************** skiplist::~skiplist() { listnodeptr nodeptr, next; nodeptr = head->getnextnode(0); while (nodeptr != NULL) { next = nodeptr->getnextnode(0); delete nodeptr; nodeptr = next; } delete head; } //***************************************************** int skiplist::search(datatype data) { listnodeptr next, nodeptr = head; for (int i=maxlevel-1;i>=0;i--) { next = nodeptr->getnextnode(i); while ((next != NULL) && (next->getdata() < data)) { nodeptr = next; next = nodeptr->getnextnode(i); } } return ((next != NULL) && (next->getdata() == data)); } //***************************************************** void skiplist::insert(datatype data) { listnodeptr next, update[maxlevel], nodeptr = head; int rlvl; int i; for (i=maxlevel-1;i>=0;i--) { next = nodeptr->getnextnode(i); while ((next != NULL) && (next->getdata() < data)) { nodeptr = next; next = nodeptr->getnextnode(i); } update[i] = nodeptr; } if ((next == NULL) || (next->getdata() != data)) { rlvl = randomlevel(); nodeptr = new(rlvl) listnode; nodeptr->setdata(data); for (i=0;isetnextnode(i, update[i]->getnextnode(i)); update[i]->setnextnode(i, nodeptr); } } } //***************************************************** void skiplist::remove(datatype data) { listnodeptr next, update[maxlevel], nodeptr = head; int i; for (i=maxlevel-1;i>=0;i--) { next = nodeptr->getnextnode(i); while ((next != NULL) && (next->getdata() < data)) { nodeptr = next; next = nodeptr->getnextnode(i); } update[i] = nodeptr; } if ((next != NULL) && (next->getdata() == data)) { i = 0; while ((igetnextnode(i) == next)) { update[i]->setnextnode(i, next->getnextnode(i)); i++; } delete next; } } //*****************************************************