动手实现 数据结构 之 “跳跃链表”
来源:互联网 发布:快速拷贝软件fastcopy 编辑:程序博客网 时间:2024/04/29 13:26
C语言 和 随机数原理 实现的跳跃链表
跳跃链表是数组二分查找的一种扩展形式,平均查找时间复杂度等价于二分查找,由能够动态的插入元素 解决了二分查找数组无法高效添加元素的问题
// 跳跃链表可以有多级指针这里简单的用 3 级指针来讲 level 3->-------------------<-->-----------------------<-->-----------------<-level 2->-------------------<-->------------<-->-------<-->-----------------<-level 1->-----------<-->----<-->----<-->----<-->-------<-->------<-->-------<-data beforeFirst 5 7 23 25 30 35 afterLast // beforeFirst 和 afterLast 作为辅助节点 各有3级指针 // 5 有 1 级指针 // 7 有 3 级指针 // 23 有 1 级指针 // 25 有 2 级指针 // 30 有 3 级指针 // 35 有 1 级指针 // // 每一个节点都可以通过左边指针找到前一个元素,右边指针找到后一个元素 // // 查找 35 不用像链表一样一个一个向后查找,可以通过高等级的指针跳跃查找 // 就比如 查找 35 不用从 5 一个一个查找到最后, // 只需通过 beforeFirst 的第三级指针找到 7,再从 7 的第三级指针找到 30,再从 30 的第一级指针找到 35 // // // 节点的指针级数是通过随机数生成的,一级指针占数组的一半,二级指针占一级指针的一半, 三级指针占二级指针的一半,以此类推 // 因此具查找效率 接近于 二分查找 // // // 跳跃链表删除 25 只需 将节点23的一级指针指向30, 把30的一级指针指向23, // 再将节点7的二级指针指向30, 把30的二级指针指向7 // 然后释放节点内存
#include <stdio.h>#include <stdlib.h>#include <time.h>typedef int bool;typedef struct Node { int level; struct Node ** front; struct Node ** back; int data;}Node;typedef struct JumpList { struct Node * beforeFirst;// 第一个元素的前一个元素 struct Node * afterLast; // 最后一个元素的后一个元素}List;#define MAX_LEVEL 5#define MAX 9999unsigned short GetLevel() { unsigned short level = 1; unsigned long randomN = (unsigned long)(rand() % MAX); double n = MAX / 2.0; while (randomN < n && level < MAX_LEVEL) { n /= 2.0; ++level; } return level;}struct Node * MakeNode(int level) { struct Node * node = (struct Node*)malloc(sizeof(struct Node)); node->front = (struct Node**)malloc(level*sizeof(struct Node*)); node->back = (struct Node**)malloc(level*sizeof(struct Node*)); node->level = level; return node;}void DestroyNode(struct Node * node) { free(node->front); // delete[] node->front free(node->back); // delete[] node->back free(node); // delete node}// 使用链表前必须 调用Initvoid Init(struct JumpList * list) { srand((unsigned)time(0)); list->beforeFirst = MakeNode(MAX_LEVEL+1); list->afterLast = MakeNode(MAX_LEVEL+1); for(int i=0; i<MAX_LEVEL; i++) { list->beforeFirst->front[i] = NULL; list->beforeFirst->back[i] = list->afterLast; list->afterLast->front[i] = list->beforeFirst; list->afterLast->back[i] = NULL; }}// 使用完需要使用Destroy将内存释放void Destroy(struct JumpList * list) { struct Node* back; for(struct Node* p=list->beforeFirst; p != list->afterLast; p=back) { back = p->back[0]; DestroyNode(p); } DestroyNode(list->afterLast);}bool IsEmpty(struct JumpList * list) { return list->beforeFirst->back[0] == list->afterLast;}// 在节点 pos 后插入一个节点 数据为datavoid InsertNodeAfter(struct Node* pos, int data) { struct Node * node = MakeNode(GetLevel()); node->data = data; struct Node * pre = pos; struct Node * nex = pos->back[0]; for(int i=0; i<node->level; i++) { node->front[i] = pre; node->back[i] = nex; pre->back[i] = node; nex->front[i] = node; while (pre->level < i+2) pre = pre->front[i]; while (nex->level < i+2) nex = nex->back[i]; }}// 删除 list 中 pos 节点 (end 前一个元素是最后一个元素,不能删除 end 因为 end 是辅助节点不用于存储)void RemoveNode(struct Node* pos) { struct Node * pre, * nex; for(int i=0; i<pos->level; i++) { pre = pos->front[i]; nex = pos->back[i]; pre->back[i] = nex; nex->front[i] = pre; } DestroyNode(pos);}// 在链表中从头到尾 查找第一个数据为data 的节点struct Node* SearchList(struct JumpList * list, int data) { int i = MAX_LEVEL-1; struct Node * node = list->beforeFirst; while (i >= 0) { if(node->back[i] == list->afterLast) { --i; } else if(data > node->back[i]->data) { --i; } else if (node->data == data) { break; } else { node = node->back[i]; } } return node;}void PrintList(struct JumpList * list) { for(struct Node* p=list->beforeFirst->back[0]; p != list->afterLast; p=p->back[0]) { printf("%d ", p->data); } printf("\n");}int main(void){ List list; Init(&list); printf("is empty %d\n",IsEmpty(&list)); InsertNodeAfter(list.beforeFirst, 1); InsertNodeAfter(list.beforeFirst, 2); InsertNodeAfter(list.beforeFirst, 3); InsertNodeAfter(list.beforeFirst, 4); InsertNodeAfter(list.beforeFirst, 5); struct Node * searchResult = SearchList(&list, 1); printf("search %d\n", searchResult->data); RemoveNode(searchResult); PrintList(&list); Destroy(&list); return 0;}
0 0
- 动手实现 数据结构 之 “跳跃链表”
- 动手实现 数据结构 之 “单向链表”
- 动手实现 数据结构 之 “双向链表”
- 动手实现 数据结构 之 “十字链表”
- 数据结构之跳跃链表
- 数据结构之跳跃链表
- 数据结构之跳跃表
- 数据结构之跳跃表
- 动手实现 数据结构 之 “栈”
- 动手实现 数据结构 之 “堆”
- 动手实现 数据结构 之 “队列”
- 动手实现 数据结构 之 “邻接链表图”
- 动手实现 数据结构 之 “二叉树”
- 动手实现 数据结构 之 “AVL树”
- 【Redis基本数据结构】跳跃表实现
- 跳跃表 SkipList【数据结构】原理及实现
- Redis底层数据结构之跳跃表
- 【数据结构】跳跃链表(Skip list)
- java 和js 秒转时分秒
- poj题目分类
- Swift学习:4.可选类型
- hdu 5178 二分查找
- Windows Phone 学习 启动器来启动短信
- 动手实现 数据结构 之 “跳跃链表”
- 学习ASP.NET MVC5框架揭秘笔记-什么是MVC模式
- 查看Linux主机的硬件信息
- substr_replace深入研究
- hdu 4965 Fast Matrix Calculation(矩阵快速幂)
- Windows Phone 学习 在程序中调用直接拨打电话
- 一个跨域请求的XSS续
- ResultSet用法集锦
- 链表算法-后面插入节点