当前位置:   article > 正文

数据结构与算法—跳表(skiplist)_跳跃表和红黑树比较

跳跃表和红黑树比较

目录

前言

跳表

查询时间分析

1、时间复杂度  o(logn)

2、空间复杂度O(n)

动态插入和删除

跳表动态更新

跳表与红黑树比较

跳表实现


前言

二分查找用的数组

链表可不可以实现二分查找呢?

跳表

        各方面性能比较优秀的动态数据结构,可以支持快速插入、删除、查找操作。写起来也不复杂,甚至可以代替红黑树

跳表特点

对链表建立一级索引,每两个节点提取一个节点到上一级,叫做索引节点。

加一层索引之后,查找一个结点需要遍历的节点个数减少了,也就是查找效率提高了。

这种查找方式就是跳表

查询时间分析

1、时间复杂度  o(logn)

  1. 在单链表中查询某个数据的时间复杂度O(N)
  2. 跳表,n个节点,会有几层索引。
  • 第k级索引的节点个数是k-1级索引节点个数的1/2;即 第k级索引节点的个数 n/2^k
  • k = log2n-1,如果包含原始链表层,整个跳表的高度是log2 n
  • 在跳表查找某个数据时,如果每一层需要遍历m个节点,那么跳表查询一个数据的时间复杂度O(m*logn)
  • m是多少? 每一级索引最多只需要遍历3个节点, m = 3 常数 

2、空间复杂度O(n)

索引节点的个数 n/2+n/4+n/8…+8+4+2=n-2 ,所以跳表的空间复杂度O(n)

意思是n个节点的单链表改成跳表,需要额外再用接近n个节点的内存空间。

在软件开发中原始链表中存储的有可能是很大的对象,而索引节点只需要存储关键值和几个指针,并不需要存储对象。所以当对象所以节点很大时,索引占用的空间可以忽略不计了。

动态插入和删除

插入、删除操作时间复杂度O(logn)

查找,需要遍历每个节点。查找时间复杂度O(logn)

删除,要拿到前驱节点,如果是双向链表,不需要考虑这个问题。

跳表动态更新

  • 插入数据,如果跳表不更新,跳表会退化成单链表。
  • 跳表通过随机函数维护 “平衡性”
  • 往跳表中插入数据时,同时将数据插入到索引层中。(哪个索引层?)

        通过随机函数,决定这个点插入到哪几级索引,如随机函数生成K,则节点添加到第一级到第K级索引中。 

跳表与红黑树比较

1,按照区间查找数据,红黑树的效率没有跳表高。跳表O(logn)

2、跳表灵活,通过改变索引结构,有效平衡执行效率和内存消耗

3、红黑树一般有现成的可用,跳表需要自己实现

跳表实现

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<assert.h>
  4. #include<string.h>
  5. typedef struct _node
  6. {
  7. int key;
  8. int value;
  9. int max_level;
  10. struct _node *next[0];
  11. }node;
  12. typedef struct _skiplist
  13. {
  14. int level;
  15. int count;
  16. node *head;
  17. }skiplist;
  18. #define offsetof(TYPE,MEMBER) ((size_t) & ((TYPE *)0)->MEMBER)
  19. #define container(ptr,type,member) ({\
  20. const typeof( ((type *)0)->member) *__mptr = (ptr);\
  21. (type *) ( (char *)__mptr - offsetof(type,member));})
  22. node * skip_list_create_node(int level,int key,int value)
  23. {
  24. node *tmp = NULL;
  25. tmp = (node *)malloc(sizeof(node) + level*sizeof(node*));
  26. assert(tmp !=NULL);
  27. memset(tmp,0,sizeof(node) + level * sizeof(node*));
  28. tmp->key = key;
  29. tmp->value = value;
  30. tmp->max_level = level;
  31. return tmp;
  32. }
  33. skiplist *skip_list_create(int max_level)
  34. {
  35. int i=0;
  36. skiplist *list = NULL;
  37. list = (skiplist *)malloc(sizeof(skiplist));
  38. assert(list != NULL);
  39. list->level = 1;
  40. list->count = 0;
  41. list->head = skip_list_create_node(max_level,0,0);
  42. if(list->head == NULL)
  43. {
  44. free(list);
  45. return NULL;
  46. }
  47. return list;
  48. }
  49. void skip_list_destory(skiplist *list)
  50. {
  51. int i = 0;
  52. node *tmp = NULL;
  53. if((list == NULL) || list->head == NULL)
  54. {
  55. return ;
  56. }
  57. while(list->head->next[0] != NULL)
  58. {
  59. tmp = list->head->next[0];
  60. list->head->next[0] = tmp->next[0];
  61. free(tmp);
  62. }
  63. free(list->head);
  64. free(list);
  65. return;
  66. }
  67. int skip_list_level(skiplist *list)
  68. {
  69. int i = 0;
  70. int level = 1;
  71. for(i = 0;i<list->head->max_level;i++)
  72. {
  73. if(rand()%2 == 1)
  74. level++;
  75. }
  76. return level;
  77. }
  78. int skip_list_insert(skiplist *list,int key,int value)
  79. {
  80. int i = 0;
  81. int level = 0;
  82. node **update = NULL;
  83. node *tmp = NULL;
  84. node *prev = NULL;
  85. if(list == NULL)
  86. return 1;
  87. update = (node **)malloc(sizeof(node *)*list->head->max_level);
  88. if(update == NULL)
  89. return 2;
  90. prev = list->head;
  91. for(i = (list->level - 1);i>=0;i--)
  92. {
  93. while(((tmp = prev->next[i]) != NULL) && (tmp->key < key))
  94. {
  95. prev = tmp;
  96. }
  97. update[i] = prev;
  98. }
  99. if((tmp != NULL) && (tmp->key == key))
  100. return 3;
  101. //get ramdon level
  102. level = skip_list_level(list);
  103. tmp = skip_list_create_node(level,key,value);
  104. if(tmp == NULL)
  105. return 4;
  106. //update max level,update
  107. if(level > list->level)
  108. {
  109. for(i = list->level;i<level;i++)
  110. {
  111. update[i] = list->head;
  112. }
  113. list->level = level;
  114. }
  115. //update node pointer
  116. for(i = 0;i<level;i++)
  117. {
  118. tmp->next[i] = update[i]->next[i];
  119. update[i]->next[i] = tmp;
  120. }
  121. list->count++;
  122. return 0;
  123. }
  124. int skip_list_search(skiplist *list,int key,int *value)
  125. {
  126. int i=0;
  127. node *prev = NULL;
  128. node *tmp = NULL;
  129. if((list == NULL) || (list->count == 0) || (value == NULL))
  130. {
  131. return 1;
  132. }
  133. prev = list->head;
  134. for(i = list->level - 1;i >= 0;i--)
  135. {
  136. //while(((tmp == prev->next[i])!=NULL) && (tmp->key<=key))
  137. while(((tmp = prev->next[i]) != NULL) && (tmp->key <= key))
  138. {
  139. if(tmp->key == key)
  140. {
  141. *value = tmp->value;
  142. return 0;
  143. }
  144. prev = tmp;
  145. }
  146. }
  147. return -1;
  148. }
  149. void skip_list_dump(skiplist *list)
  150. {
  151. int i = 0;
  152. node *ptmp = NULL;
  153. printf("\r\n skiplist level[%d],count[%d]",list->level,list->count);
  154. for(i = list->level -1 ;i>=0;i--)
  155. {
  156. ptmp = list->head->next[i];
  157. printf("\r\n level[%d]:",i);
  158. while(ptmp != NULL)
  159. {
  160. printf("%d-%d ",ptmp->key,ptmp->value);
  161. ptmp = ptmp->next[i];
  162. }
  163. }
  164. printf("\r\n-----------------------------------\n");
  165. return;
  166. }
  167. int skip_list_delete(skiplist *list,int key,int *value)
  168. {
  169. int i = 0;
  170. node **update = NULL;
  171. node *tmp = NULL;
  172. node *prev = NULL;
  173. if((list == NULL) && value == NULL || list->count ==0)
  174. return 1;
  175. update = (node **)malloc(sizeof(node *)*list->level);
  176. if(update == NULL)
  177. return 2;
  178. prev = list->head;
  179. for(i = (list->level - 1);i>=0;i++)
  180. {
  181. while((tmp = prev->next[i]) != NULL && (tmp->key < key))
  182. {
  183. prev=tmp;
  184. }
  185. update[i] = prev;
  186. }
  187. if((tmp != NULL) && (tmp->key == key))
  188. {
  189. *value = tmp->value;
  190. for(i = 0;i<list->level;i++)
  191. {
  192. if(update[i]->next[i] == tmp)
  193. {
  194. update[i]->next[i] = tmp->next[i];
  195. }
  196. }
  197. free(tmp);
  198. tmp = NULL;
  199. for(i = list->level -1 ;i>=0 ;i++)
  200. {
  201. if(list->head->next[i]==NULL)
  202. list->level--;
  203. else
  204. break;
  205. }
  206. list->count--;
  207. }
  208. else
  209. return 3;//not find
  210. return 0;
  211. }
  212. int main()
  213. {
  214. int res = 0;
  215. int key = 0;
  216. int value = 0;
  217. skiplist *list = NULL;
  218. list = skip_list_create(8);
  219. assert(list != NULL);
  220. int i=0;
  221. for(i = 0;i<30;i++)
  222. {
  223. key = value = i;
  224. res = skip_list_insert(list,key,value);
  225. if(res !=0)
  226. {
  227. printf("insert error res=%d\n",res);
  228. }
  229. }
  230. printf("insert down\n");
  231. skip_list_dump(list);
  232. printf("############search#######\n");
  233. key = 10;
  234. skip_list_search(list,key,&value);
  235. printf("search value=%d\n",value);
  236. printf("############del############\n");
  237. skip_list_delete(list,key,&value);
  238. printf("del value=%d\n",value);
  239. skip_list_dump(list);
  240. }
  1. # ./a.out
  2. insert down
  3. skiplist level[8],count[30]
  4. level[7]:15-15
  5. level[6]:15-15 16-16 23-23
  6. level[5]:0-0 1-1 5-5 8-8 14-14 15-15 16-16 19-19 22-22 23-23 24-24
  7. level[4]:0-0 1-1 3-3 4-4 5-5 6-6 7-7 8-8 13-13 14-14 15-15 16-16 17-17 18-18 19-19 22-22 23-23 24-24 27-27 29-29
  8. level[3]:0-0 1-1 2-2 3-3 4-4 5-5 6-6 7-7 8-8 9-9 10-10 13-13 14-14 15-15 16-16 17-17 18-18 19-19 20-20 21-21 22-22 23-23 24-24 25-25 26-26 27-27 28-28 29-29
  9. level[2]:0-0 1-1 2-2 3-3 4-4 5-5 6-6 7-7 8-8 9-9 10-10 11-11 12-12 13-13 14-14 15-15 16-16 17-17 18-18 19-19 20-20 21-21 22-22 23-23 24-24 25-25 26-26 27-27 28-28 29-29
  10. level[1]:0-0 1-1 2-2 3-3 4-4 5-5 6-6 7-7 8-8 9-9 10-10 11-11 12-12 13-13 14-14 15-15 16-16 17-17 18-18 19-19 20-20 21-21 22-22 23-23 24-24 25-25 26-26 27-27 28-28 29-29
  11. level[0]:0-0 1-1 2-2 3-3 4-4 5-5 6-6 7-7 8-8 9-9 10-10 11-11 12-12 13-13 14-14 15-15 16-16 17-17 18-18 19-19 20-20 21-21 22-22 23-23 24-24 25-25 26-26 27-27 28-28 29-29
  12. -----------------------------------
  13. ############search############
  14. search value=10
  15. ############del############
  16. del value=10
  17. skiplist level[8],count[29]
  18. level[7]:15-15
  19. level[6]:15-15 16-16 23-23
  20. level[5]:0-0 1-1 5-5 8-8 14-14 15-15 16-16 19-19 22-22 23-23 24-24
  21. level[4]:0-0 1-1 3-3 4-4 5-5 6-6 7-7 8-8 13-13 14-14 15-15 16-16 17-17 18-18 19-19 22-22 23-23 24-24 27-27 29-29
  22. level[3]:0-0 1-1 2-2 3-3 4-4 5-5 6-6 7-7 8-8 9-9 13-13 14-14 15-15 16-16 17-17 18-18 19-19 20-20 21-21 22-22 23-23 24-24 25-25 26-26 27-27 28-28 29-29
  23. level[2]:0-0 1-1 2-2 3-3 4-4 5-5 6-6 7-7 8-8 9-9 11-11 12-12 13-13 14-14 15-15 16-16 17-17 18-18 19-19 20-20 21-21 22-22 23-23 24-24 25-25 26-26 27-27 28-28 29-29
  24. level[1]:0-0 1-1 2-2 3-3 4-4 5-5 6-6 7-7 8-8 9-9 11-11 12-12 13-13 14-14 15-15 16-16 17-17 18-18 19-19 20-20 21-21 22-22 23-23 24-24 25-25 26-26 27-27 28-28 29-29
  25. level[0]:0-0 1-1 2-2 3-3 4-4 5-5 6-6 7-7 8-8 9-9 11-11 12-12 13-13 14-14 15-15 16-16 17-17 18-18 19-19 20-20 21-21 22-22 23-23 24-24 25-25 26-26 27-27 28-28 29-29
  26. -----------------------------------

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号