跳转表(skip lists)

来源:互联网 发布:mac win10截屏快捷键 编辑:程序博客网 时间:2024/04/30 05:57
跳转表(skip lists)

      跳转表是动态平衡数据结构( balanced dynamic search structure )的一种, 动态平衡数据结构还包括AVL树,2-3-4数,B数,红黑树,Treaps等.

      跳转表由William Pugh在1989年创造,相对其他动态平衡数据结构,它具有容易编码实现的优点.

      跳转表的一次操作(包括某个元素的插入,删除和查找)绝大多数情况下能够在O(lgn)的期望时间内执行完毕,而且这个概率是相当高的.

      跳转表是在有序链表的基础上发展起来的(在本人实现中采用单链表实现,使用双链表也可以),它的想法来源于高速地铁与慢速地铁,高速地铁所到达的站与站之间的距离较远,而慢速地铁的距离较近,我们可以乘坐高速地铁到达离目的地最近的车站再转乘慢速地铁达到目的地.如下图所示,我们要到达目的地59,先乘坐高速地铁达到42,再转乘慢速地铁达到59.


 代码如下:
[cpp] view plaincopy
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <time.h>  
  4. #include <malloc.h>  
  5.   
  6. typedef struct SkipNode  
  7. {  
  8.   int key;  
  9.   struct SkipNode* next[1];  
  10. }SkipNode;  
  11.   
  12. #define MaxNumOfLevels 16  
  13. #define MaxLevel (MaxNumOfLevels-1)  
  14.   
  15. #define newSkipNode(n) (SkipNode*)malloc(sizeof(SkipNode)+n*sizeof(SkipNode*))  
  16.   
  17. typedef struct SkipList  
  18. {  
  19.   int level;  
  20.   SkipNode* header;  
  21. }SkipList;  
  22.   
  23. #define true    1  
  24. #define false   0  
  25.   
  26. SkipNode *NILnode;  
  27.   
  28. void init()  
  29. {  
  30.   NILnode = newSkipNode(0);  
  31.   NILnode->key = 0x7fffffff;  
  32. }  
  33.   
  34. SkipList* newSkipList()  
  35. {  
  36.   SkipList* list;  
  37.   list = (SkipList*)malloc(sizeof(SkipList));  
  38.   list->level=0;  
  39.   // it's convenient to add a head node in the Skip List  
  40.   list->header = newSkipNode(MaxLevel);  
  41.   int i;  
  42.   for(i=0; i<MaxNumOfLevels; i++)  
  43.     list->header->next[i] = NILnode;  
  44.   return list;  
  45. }  
  46.   
  47.   
  48. void freeSkipList(SkipList** plist)  
  49. {  
  50.   SkipNode* nd = (*plist)->header;  
  51.   SkipNode* p;  
  52.   // free each node in the bottom List including head node  
  53.   while (nd!=NILnode)  
  54.   {  
  55.     p = nd;  
  56.     nd = nd->next[0];  
  57.     free(p);  
  58.   }  
  59.   free(*plist);  
  60.   plist = NULL;  
  61. }  
  62.   
  63.   
  64. int randLevel()  
  65. {  
  66.   int randnum = rand(); // 32bit data  
  67.   int i;  
  68.   for (i=0; i<MaxLevel; i++)  
  69.   {  
  70.     // chech whether bit 2*i and 2*i+1 is both zero  
  71.     if (randnum==0 || randnum&3!=0)  
  72.       break;  
  73.     randnum >>= 2;  
  74.   }  
  75.   return i;  
  76. }  
  77.   
  78.   
  79. int insertSkipList(SkipList* list, int key)  
  80. {  
  81.   SkipNode* nd = list->header;  
  82.   SkipNode* update[MaxNumOfLevels];  
  83.   int level = list->level;  
  84.   while (level >= 0)  
  85.   {  
  86.     // found each pre node in each level of   
  87.     while (nd->next[level]->key < key)  
  88.       nd = nd->next[level];  
  89.     update[level] = nd;  
  90.     level--;  
  91.   }  
  92.   if (nd->next[0]->key == key)  
  93.     return false;  
  94.   int nl = randLevel();  
  95.   level = list->level;  
  96.   if (level < nl)  
  97.   {  
  98.     while (++level <= nl)  
  99.       update[level] = list->header;  
  100.     list->level = nl;  
  101.   }  
  102.   nd = newSkipNode(nl);  
  103.   nd->key = key;  
  104.   int i;  
  105.   for(i = nl; i>=0; i--)  
  106.   {  
  107.     SkipNode* tmp = update[i]->next[i];  
  108.     update[i]->next[i] = nd;  
  109.     nd->next[i] = tmp;  
  110.   }  
  111.   return true;  
  112. }  
  113.   
  114.   
  115. int deleteSkipList(SkipList* list, int key)  
  116. {  
  117.   SkipNode* nd = list->header;  
  118.   SkipNode* update[MaxNumOfLevels];  
  119.   int level = list->level;  
  120.   int ndlevel = -1;  
  121.   printf(">>Delete %d: ",key);  
  122.   while (level >= 0)  
  123.   {  
  124.     while (nd->next[level]->key < key)  
  125.       nd = nd->next[level];  
  126.     printf("%d ",nd->key);  
  127.     // get the level of the node to be deleted  
  128.     if (ndlevel == -1 && nd->next[level]->key == key)  
  129.       ndlevel = level;  
  130.     update[level] = nd;  
  131.     level--;  
  132.   }  
  133.   nd = nd->next[0];  
  134.   // if the node to be deleted is not in the Skip List  
  135.   if (nd->key != key)  
  136.     return false;  
  137.   int i;  
  138.   // modify all nodes in update list from the level  
  139.   // of the node to be deleted  
  140.   for (i=ndlevel; i>=0; i--)  
  141.   {  
  142.     update[i]->next[i] = nd->next[i];  
  143.     if (list->header->next[i] == NILnode)  
  144.       list->level--;  
  145.   }  
  146.   free(nd);  
  147.   return true;  
  148. }  
  149.   
  150.   
  151. int searchSkipList(SkipList* list, int key)  
  152. {  
  153.   printf(">>Search %d: ",key);  
  154.   SkipNode* nd = list->header;  
  155.   int level = list->level;  
  156.   while (level >= 0)  
  157.   {  
  158.     while (nd->next[level]->key <= key)  
  159.       nd = nd->next[level];  
  160.     printf("%d ",nd->key);  
  161.     // have found the node of correct key  
  162.     if (nd->key == key)  
  163.       return true;  
  164.     level--;  
  165.   }  
  166.   return false;  
  167. }  
  168.   
  169.   
  170. void outputSkipList(SkipList* list)  
  171. {  
  172.   int level = list->level;  
  173.   printf(">>%d\n", level);  
  174.   while (level >= 0)  
  175.   {  
  176.     SkipNode* nd = list->header->next[level];  
  177.     while (nd != NILnode)  
  178.     {  
  179.       printf("%d ",nd->key);  
  180.       nd = nd->next[level];  
  181.     }  
  182.     printf("\n");  
  183.     level--;  
  184.   }  
  185. }  
  186.   
  187.   
  188. int main()  
  189. {  
  190.   const int n = 20;  
  191.   int a[] = {53, 13, 4, 9, 31, 26, 16, 19, 62, 64, 41, 43, 47, 58, 52, 83, 89, 73, 79, 59};  
  192.   init();  
  193.   SkipList *list = newSkipList();  
  194.   //srand(time(0));  
  195.   int i;  
  196.   for(i=0; i<n; i++)  
  197.   {  
  198.     int ok=insertSkipList(list,a[i]);  
  199.     if (!ok)  
  200.       printf("Duplicated Data: %d\n", a[i]);  
  201.   }  
  202.   outputSkipList(list);  
  203. //   int ok = searchSkipList(list, 43);  
  204. //   if (ok)  
  205. //     printf("found\n");  
  206.   int ok = deleteSkipList(list, 41);  
  207.   if (ok)  
  208.     printf("deleted\n");  
  209.   outputSkipList(list);  
  210.   freeSkipList(&list);  
  211. }

参考来源:http://blog.csdn.net/linyunzju/article/details/7619987
原创粉丝点击