标签:
1、简介
跳跃列表(也称跳表)是一种随机化数据结构,基于并联的链表,其效率可比拟于二叉查找树(对于大多数操作需要O(log n)平均时间)。
基本上,跳跃列表是对有序的链表增加上附加的前进链接,增加是以随机化的方式进行的,所以在列表中的查找可以快速的跳过部分列表,因此得名。所有操作都以对数随机化的时间进行。
跳跃表数据结构:
1 #define MAX_LEVEL 31 2 3 struct node 4 { 5 int key; 6 int value; 7 struct node *forward[1]; 8 }; 9 10 struct skiplist 11 { 12 int level; 13 struct node *list_head; 14 }; 15 16 #define NIL list->list_head
初始化:
1 int skiplist_init(struct skiplist *list) 2 { 3 int i; 4 list->list_head = (struct node *)malloc(sizeof(struct node) + MAX_LEVEL * sizeof(struct node *)); 5 if (list->list_head == NULL) 6 return -1; 7 8 for (i = 0; i <= MAX_LEVEL; i++) 9 list->list_head->forward[i] = NIL; 10 list->level = 0; 11 return 0; 12 }
2、跳表操作
2.1 查找
如下图,查找12时的查找路径
1 int skiplist_find(struct skiplist *list, int key, int *value) 2 { 3 int i, level_new; 4 struct node *pn = NULL; 5 6 /* find insert position */ 7 pn = list->list_head; 8 for (i = list->level; i >= 0; i--) 9 { 10 while ((pn->forward[i] != NIL) && (pn->forward[i]->key < key)) 11 pn = pn->forward[i]; 12 } 13 pn = pn->forward[0]; 14 if ((pn != NIL) && (pn->key == key)) 15 { 16 *value = pn->value; 17 return 0; 18 } 19 20 return -1; 21 }
2.2 插入
插入17时的路径如图,需要
a) 找到插入位置
b) 更新forward
1 int skiplist_insert(struct skiplist *list, int key, int value) 2 { 3 int i, level_new; 4 struct node *update[MAX_LEVEL + 1] = {NULL}; 5 struct node *pn = NULL; 6 7 /* find insert position */ 8 pn = list->list_head; 9 for (i = list->level; i >= 0; i--) 10 { 11 while ((pn->forward[i] != NIL) && (pn->forward[i]->key < key)) 12 pn = pn->forward[i]; 13 update[i] = pn; 14 } 15 pn = pn->forward[0]; 16 if ((pn != NIL) && (pn->key == key)) 17 return -1; 18 19 /* determine level */ 20 for (level_new = 0; (rand() < RAND_MAX / 2) && (level_new < MAX_LEVEL); level_new++); 21 22 if (level_new > list->level) 23 { 24 for (i = list->level + 1; i <= level_new; i++) 25 update[i] = NIL; 26 list->level = level_new; 27 } 28 29 /* make new node */ 30 pn = (struct node *)malloc(sizeof(struct node) + list->level * sizeof(struct node *)); 31 if (pn == NULL) 32 return -1; 33 pn->key = key; 34 pn->value = value; 35 36 /* update forward links */ 37 for (i = 0; i <= level_new; i++) 38 { 39 pn->forward[i] = update[i]->forward[i]; 40 update[i]->forward[i] = pn; 41 } 42 43 return 0; 44 }
2.3 删除
1 int skiplist_delete(struct skiplist *list, int key) 2 { 3 int i, level_new; 4 struct node *update[MAX_LEVEL + 1] = {NULL}; 5 struct node *pn = NULL; 6 7 /* find insert position */ 8 pn = list->list_head; 9 for (i = list->level; i >= 0; i--) 10 { 11 while ((pn->forward[i] != NIL) && (pn->forward[i]->key < key)) 12 pn = pn->forward[i]; 13 update[i] = pn; 14 } 15 pn = pn->forward[0]; 16 if ((pn == NIL) || (pn->key != key)) 17 return -1; 18 19 /* adjust forward pointers */ 20 for (i = 0; i <= list->level; i++) 21 { 22 if (update[i]->forward[i] != pn) 23 break; 24 update[i]->forward[i] = pn->forward[i]; 25 } 26 27 free(pn); 28 29 /* adjust list level */ 30 while ((list->level > 0) && (list->list_head->forward[list->level] == NIL)) 31 list->level--; 32 33 return 0; 34 }
2.4 跳跃表遍历
1 void skiplist_show(struct skiplist *list) 2 { 3 int i; 4 int table[MAX_LEVEL + 1] = {0}; 5 struct node *pn = NULL; 6 7 for (i = 0; i <= list->level; i++) 8 { 9 pn = list->list_head; 10 printf("%d level:\n", i); 11 while (pn->forward[i] != NIL) 12 { 13 pn = pn->forward[i]; 14 #ifdef FULL_LIST 15 printf("<%d> -> ", pn->key); 16 #endif 17 table[i]++; 18 } 19 printf("Total %d nodes\n", table[i]); 20 } 21 22 }
3、调表性能分析
标签:
原文地址:http://www.cnblogs.com/ym65536/p/4375243.html