cs 261 - winter 2010
DESCRIPTION
CS 261 - Winter 2010. Skip Lists. Skip Lists Advantages. Ordinary linked lists and arrays have fast (O(1)) addition, but slow search Sorted Vectors have fast search (O(log n)) but slow insertion Skip Lists have it all - fast (O(log n)) addition, search and removal times! - PowerPoint PPT PresentationTRANSCRIPT
![Page 1: CS 261 - Winter 2010](https://reader035.vdocuments.us/reader035/viewer/2022081501/5681452d550346895db1f1b4/html5/thumbnails/1.jpg)
CS 261 - Winter 2010
Skip Lists
![Page 2: CS 261 - Winter 2010](https://reader035.vdocuments.us/reader035/viewer/2022081501/5681452d550346895db1f1b4/html5/thumbnails/2.jpg)
Skip Lists Advantages
• Ordinary linked lists and arrays have fast (O(1)) addition, but slow search
• Sorted Vectors have fast search (O(log n)) but slow insertion
• Skip Lists have it all - fast (O(log n)) addition, search and removal times!
• Cost - Slightly more complicated
![Page 3: CS 261 - Winter 2010](https://reader035.vdocuments.us/reader035/viewer/2022081501/5681452d550346895db1f1b4/html5/thumbnails/3.jpg)
Start with an ordered listLets begin with a simple ordered list, sentinel on
the left, single links.
![Page 4: CS 261 - Winter 2010](https://reader035.vdocuments.us/reader035/viewer/2022081501/5681452d550346895db1f1b4/html5/thumbnails/4.jpg)
Start of the struct definition
struct skiplist {
struct skiplink * sentinel;
int size;
};
![Page 5: CS 261 - Winter 2010](https://reader035.vdocuments.us/reader035/viewer/2022081501/5681452d550346895db1f1b4/html5/thumbnails/5.jpg)
Operations
• Add (Object newValue) - find correct location, add the value
• Contains (Object testValue) - find correct location, see if its what we want
• Remove (Object testValue) - find correct location, possibly remove it
• See anything in common?
![Page 6: CS 261 - Winter 2010](https://reader035.vdocuments.us/reader035/viewer/2022081501/5681452d550346895db1f1b4/html5/thumbnails/6.jpg)
Slide Right
struct skiplink * slideRight (struct skiplink * current, EleType testValue) {
while ((current->next != 0) && LT(current->next->value, testValue))
current = current->next; return current;}
Finds the link RIGHT BEFORE the place the value we want should be, if it is there
![Page 7: CS 261 - Winter 2010](https://reader035.vdocuments.us/reader035/viewer/2022081501/5681452d550346895db1f1b4/html5/thumbnails/7.jpg)
Add (EleType newValue)
void add (struct skiplist* lst, EleType newValue) { struct skiplink * current = slideRight(lst->sentinel, newValue); struct link * newLink = (struct link *) malloc(sizeof(struct
link)); assert (newLink != 0); newLink->value = newValue; newLink->next = current->next; current->next = newLink; lst->size++;}
![Page 8: CS 261 - Winter 2010](https://reader035.vdocuments.us/reader035/viewer/2022081501/5681452d550346895db1f1b4/html5/thumbnails/8.jpg)
Contains (EleType testValue)
int contains (struct skip *lst, EleType testValue) {
struct skiplink * current =
slideRight (lst->leftSentinel, testValue);
if ((current->next != 0) &&
(EQ(testValue, current->next->value)))
return true;
return false;
} /* reminder, this is one level list, not real skiplist */
![Page 9: CS 261 - Winter 2010](https://reader035.vdocuments.us/reader035/viewer/2022081501/5681452d550346895db1f1b4/html5/thumbnails/9.jpg)
Remove (Object testValue)
void remove (struct skiplist *lst, EleType testValue) { struct skiplink * current = slideRight (lst->leftSentinel, testValue); if ((current->next != 0) && (EQ(testValue, current->next->value))) { current->next = current->next->next; free(current->next); lst->size--; } }
![Page 10: CS 261 - Winter 2010](https://reader035.vdocuments.us/reader035/viewer/2022081501/5681452d550346895db1f1b4/html5/thumbnails/10.jpg)
Problem with Sorted List
• What’s the use?
• Add is still O(n), so is contains, so is remove.
• No better than an ordinary list.
• Major problem with list - sequential access
![Page 11: CS 261 - Winter 2010](https://reader035.vdocuments.us/reader035/viewer/2022081501/5681452d550346895db1f1b4/html5/thumbnails/11.jpg)
Why no binary search?What if we kept a link to middle of list?
![Page 12: CS 261 - Winter 2010](https://reader035.vdocuments.us/reader035/viewer/2022081501/5681452d550346895db1f1b4/html5/thumbnails/12.jpg)
But need to keep going
![Page 13: CS 261 - Winter 2010](https://reader035.vdocuments.us/reader035/viewer/2022081501/5681452d550346895db1f1b4/html5/thumbnails/13.jpg)
And going and going
![Page 14: CS 261 - Winter 2010](https://reader035.vdocuments.us/reader035/viewer/2022081501/5681452d550346895db1f1b4/html5/thumbnails/14.jpg)
In theory it would work…..
• In theory this would work
• Would give us nice O(log n) search
• But would be really hard to maintain as values were inserted and removed
• What about if we relax the rules, and don’t try to be so precise…..
![Page 15: CS 261 - Winter 2010](https://reader035.vdocuments.us/reader035/viewer/2022081501/5681452d550346895db1f1b4/html5/thumbnails/15.jpg)
The power of probability
• Instead of being precise, keep a hierarchy of ordered lists with downward pointers
• Each list has approximately half the elements of the one below
• So, if the bottom list has n elements, how many levels are there??
![Page 16: CS 261 - Winter 2010](https://reader035.vdocuments.us/reader035/viewer/2022081501/5681452d550346895db1f1b4/html5/thumbnails/16.jpg)
Picture of Skip List
![Page 17: CS 261 - Winter 2010](https://reader035.vdocuments.us/reader035/viewer/2022081501/5681452d550346895db1f1b4/html5/thumbnails/17.jpg)
Slightly bigger list
![Page 18: CS 261 - Winter 2010](https://reader035.vdocuments.us/reader035/viewer/2022081501/5681452d550346895db1f1b4/html5/thumbnails/18.jpg)
Contains (Object testValue)
• Starting at topmost sentinel, slide right
• If next value is it, return true
• If next value is not what we are looking for, move down and slide right
• If we get to bottom without finding it, return false
![Page 19: CS 261 - Winter 2010](https://reader035.vdocuments.us/reader035/viewer/2022081501/5681452d550346895db1f1b4/html5/thumbnails/19.jpg)
Notes about contains
• See how it makes a zig-zag from top to bottom
• On average, slide only moves one or two positions
• So basically proportional to height of structure
• Which is????? O( ?? )
![Page 20: CS 261 - Winter 2010](https://reader035.vdocuments.us/reader035/viewer/2022081501/5681452d550346895db1f1b4/html5/thumbnails/20.jpg)
Remove Algorithm
• Start at topmost sentinal
• Loop as follows– Slide right. If next element is the one we
want, remove it – If no down element, reduce size– Move down
![Page 21: CS 261 - Winter 2010](https://reader035.vdocuments.us/reader035/viewer/2022081501/5681452d550346895db1f1b4/html5/thumbnails/21.jpg)
Notice about Remove
• Only want to decrement size counter if at bottom level
• Again, makes zig-zag motion to bottom, is proportional to height
• So it is again O(log n)
![Page 22: CS 261 - Winter 2010](https://reader035.vdocuments.us/reader035/viewer/2022081501/5681452d550346895db1f1b4/html5/thumbnails/22.jpg)
Add (Object newElement)
• Now we come to addition - the most complex operation.
• Intuitive idea - add to bottom row (remember to increment count)
• Move upwards, flipping a coin• As long as heads, add to next higher row• At top, again flip, if heads make new row
![Page 23: CS 261 - Winter 2010](https://reader035.vdocuments.us/reader035/viewer/2022081501/5681452d550346895db1f1b4/html5/thumbnails/23.jpg)
Add ExampleInsert the following: 9 14 7 3 20
Coin toss: T H T H H T T H T (insert if heads)
![Page 24: CS 261 - Winter 2010](https://reader035.vdocuments.us/reader035/viewer/2022081501/5681452d550346895db1f1b4/html5/thumbnails/24.jpg)
The Power of Chance
• At each step we flip a coin• So the exact structure is not predictable,
and will be different even if you add the same elements in same order over again
• But the gross structure is predictable, because if you flip a coin N times as N gets large you expect N/2 to be heads.
![Page 25: CS 261 - Winter 2010](https://reader035.vdocuments.us/reader035/viewer/2022081501/5681452d550346895db1f1b4/html5/thumbnails/25.jpg)
Notes on Add
• Again proportional to height of structure, not number of nodes in list
• So also O(log n)
• So all three operations are O(log n) !
• By far the fastest overall Bag structure we have seen!
• (Downside - does use a lot of memory as values are repeated. But who cares about memory? )
![Page 26: CS 261 - Winter 2010](https://reader035.vdocuments.us/reader035/viewer/2022081501/5681452d550346895db1f1b4/html5/thumbnails/26.jpg)
int skipListContains(struct skipList* slst, EleType d) {
struct skipLink *tmp = slst->topSentinel;
while (tmp != 0) { tmp = slideRight(tmp, d); if ((tmp->next != 0) && EQ(d, tmp->next->value))
return 1; tmp = tmp->down; } return 0;}
![Page 27: CS 261 - Winter 2010](https://reader035.vdocuments.us/reader035/viewer/2022081501/5681452d550346895db1f1b4/html5/thumbnails/27.jpg)
void skipListAdd(struct skipList * slst, EleType d) {
struct skipLink *downLink, *newLink; downLink = skipLinkAdd(slideRight(slst->topSentinel,d),d);
if (downLink != 0 && skipFlip()) { newLink = newSkipLink(d, 0, downLink);
slst->topSentinel = newSkipLink(0, newLink, slst->topSentinel);
} slst->size++;}
![Page 28: CS 261 - Winter 2010](https://reader035.vdocuments.us/reader035/viewer/2022081501/5681452d550346895db1f1b4/html5/thumbnails/28.jpg)
struct skipLink* skipLinkAdd(struct skipLink * current, EleType d) {
struct skipLink *newLink, *downLink; newLink = 0; if (current->down == 0) { newLink = newSkipLink(d, current->next, 0); current->next = newLink; } else { downLink = skipLinkAdd(slideRight(current-
>down, d), d); if (downLink != 0 && skipFlip()) { newLink = newSkipLink(d, current-
>next, downLink); current->next = newLink; } } return newLink;}
![Page 29: CS 261 - Winter 2010](https://reader035.vdocuments.us/reader035/viewer/2022081501/5681452d550346895db1f1b4/html5/thumbnails/29.jpg)
struct skipLink* newSkipLink(EleType d, struct skipLink * nlnk, struct skipLink* dlnk) {
struct skipLink * tmp = (struct skipLink *) malloc(sizeof(struct skipLink));
assert(tmp != 0); tmp->value = d; tmp->next = nlnk; tmp->down = dlnk; return tmp;}
![Page 30: CS 261 - Winter 2010](https://reader035.vdocuments.us/reader035/viewer/2022081501/5681452d550346895db1f1b4/html5/thumbnails/30.jpg)
int skipFlip() { return rand() % 2; }
![Page 31: CS 261 - Winter 2010](https://reader035.vdocuments.us/reader035/viewer/2022081501/5681452d550346895db1f1b4/html5/thumbnails/31.jpg)
void skipListRemove(struct skipList* slst, EleType d) { struct skipLink *current, *tmp; current = slst->topSentinel; while (current != 0) { current = slideRight(current, d); if (current->next != 0 && EQ(d,
current->next->value)) { tmp = current->next; current->next = current->next-
>next; free(tmp); if (current->down != 0) slst->size--; } current = current->down; }}