跳表(skiplist)
来源:互联网 发布:无人深空低配优化补丁 编辑:程序博客网 时间:2024/06/09 23:39
之前看随机化的平衡树时看到了跳表这种数据结构,在网上查了些资料,自己实现了一下,确实比各种平衡树好写多了,并且效率也不低。
跳表这种数据结构其实就是对链表的扩展,采用多层链表的形式,每高一层节点数量大约减少1/2。
例如:
1-------------->5----------------->null
1----->3------>5----->7-------->null
1->2->3->4->5->6->7->8--->null
这样我们在查找某个节点时就可以从高层开始查找,一旦该层到末尾,或下一个值大于查找值,我们就跳到下一层。
比如我们要查找6:
(1)首先跳到第三层的第一个节点1.
(2)节点1的下一个节点5小于6,跳到该点。
(3)节点5下一个节点为空,调到第二层。
(4)第二层的节点5下一个节点7大于6,跳第一层.
(5)第一层下一个节点为6,ok找到目标。
1.代码
我用python简单的写了一下,本来还想研究一下怎么找第k大的,然而没看到相关的资料,之后再补充把。
(1)节点类
import randomclass node(object): def __init__(self,val,level): self.val = val #节点值 self.next = [None for _ in xrange(level)]#初始化next数组(2)跳表类
class skipList(object): def __init__(self,maxh): self.maxh = maxh#定义最大高度,这个值很重要,根据数据规模,选取不同的值log(n) self.next = [None for _ in xrange(maxh)] def find(self,val):#查找一个值 maxh,nex = self.maxh-1,self while maxh>=0: if not nex.next[maxh] or nex.next[maxh].val > val:maxh -= 1 else:nex = nex.next[maxh] if nex.val == val:return nex def insert(self,val):#插入一个值 maxh,nex = self.maxh-1,self nod = node(val,self.random());l = len(nod.next)-1 while maxh>=0: #print nex.next[maxh],maxh,l if not nex.next[maxh] or nex.next[maxh].val > val: if maxh <= l: nod.next[maxh] = nex.next[maxh] nex.next[maxh] = nod maxh -= 1 else:nex = nex.next[maxh] return nod def remove(self,val):#移除一个值 maxh,nex = self.maxh-1,self while maxh>=0: #print nex.next[maxh],maxh,l if not nex.next[maxh] or nex.next[maxh].val > val:maxh -= 1 if nex.next[maxh].val == val: nex.next[maxh] = nex.next[maxh].next[maxh] maxh -= 1 else:nex = nex.next[maxh] def random(self):#产生随机的层数 k = 1 while random.randint(0,1):k+=1 return k if k < self.maxh else self.maxh def travel(self,l):#打印第n层的值 nex = self;result = [] while nex.next[l]: result.append(nex.next[l].val) nex = nex.next[l] print result(3)测试
#!/usr/bin/env python# -*- coding: utf-8 -*-#pratice of skiplistimport randomclass node(object): def __init__(self,val,level): self.val = val self.next = [None for _ in xrange(level)]class skipList(object): def __init__(self,maxh): self.maxh = maxh self.next = [None for _ in xrange(maxh)] def find(self,val): maxh,nex = self.maxh-1,self while maxh>=0: if not nex.next[maxh] or nex.next[maxh].val > val:maxh -= 1 else:nex = nex.next[maxh] if nex.val == val:return nex def insert(self,val): maxh,nex = self.maxh-1,self nod = node(val,self.random());l = len(nod.next)-1 while maxh>=0: #print nex.next[maxh],maxh,l if not nex.next[maxh] or nex.next[maxh].val > val: if maxh <= l: nod.next[maxh] = nex.next[maxh] nex.next[maxh] = nod maxh -= 1 else:nex = nex.next[maxh] return nod def remove(self,val): maxh,nex = self.maxh-1,self while maxh>=0: #print nex.next[maxh],maxh,l if not nex.next[maxh] or nex.next[maxh].val > val:maxh -= 1 if nex.next[maxh].val == val: nex.next[maxh] = nex.next[maxh].next[maxh] maxh -= 1 else:nex = nex.next[maxh] def random(self): k = 1 while random.randint(0,1):k+=1 return k if k < self.maxh else self.maxh def travel(self,l): nex = self;result = [] while nex.next[l]: result.append(nex.next[l].val) nex = nex.next[l] print resultif __name__ == '__main__': a = skipList(4) for m in xrange(30,-1,-1): a.insert(m) a.remove(18) a.travel(0) a.travel(1) a.travel(2) a.travel(3) print a.find(3) print a.find(100)
结果:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
[3, 6, 7, 8, 10, 13, 14, 16, 17, 24, 25, 26, 27, 30]
[3, 8, 10, 13, 16, 26]
[13, 26]
可以看到基本上,高层都比下一层少一半左右节点。
0 0
- SkipList 跳表
- SkipList跳表
- 跳表SkipList
- SkipList 跳表
- SkipList 跳表
- 跳表SkipList
- SkipList 跳表
- SkipList 跳表
- SkipList 跳表
- SkipList 跳表
- SkipList 跳表
- 跳表SkipList
- SkipList 跳表
- SkipList 跳表
- SkipList 跳表
- SkipList 跳表
- SkipList跳表
- SkipList 跳表
- HTML学习笔记5:列表和表单
- 【JavaEE】经典JAVA EE企业应用实战-读书笔记8
- 剑指offer-----从尾到头打印链表(java版)
- Android_Bitmap你到底多大
- PAT BASIC LEVEL 1009. 说反话 (20)
- 跳表(skiplist)
- Python基本语法
- windows——UNICODE _UNICODE
- 学生信息管理系统
- 常见的加密算法分类
- service
- 使用钩子函数获取全部的鼠标消息和键盘消息
- 背包问题
- C语言模拟实现strncpy、strcat