跳表(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
原创粉丝点击