golang 实现跳表skiplist

package main

import (
	"math/rand"
	"time"
	"fmt"
)

const (
	P = 0.6
	MaxLevel = 8
)

func randomLevel() int {
	i := 1
	rand.Seed(time.Now().UnixNano())
	for i < MaxLevel {
		p := rand.Float64()
		if (p < P) {
			i++
		} else {
			break
		}
	}
	return i
}

type node struct {
	level int
	nexts []*node
	v     int
}

type skipList struct {
	head *node
}

func NewSkipList() *skipList {
	s := new(skipList)
	s.head = new(node)
	s.head.level = MaxLevel
	s.head.nexts = make([]*node, MaxLevel)
	return s
}

func (s *skipList) insert(v int) {
	l := randomLevel()
	add := new(node)
	add.level = l
	add.nexts = make([]*node, l)
	add.v = v
	i := l

	p := s.head
	for i > 0 {
		n := p.nexts[i - 1]
		for n != nil && n.v < v {
			p = n
			n = n.nexts[i - 1]
		}
		p.nexts[i - 1] = add
		add.nexts[i - 1] = n
		i --
	}
}

func (s *skipList) search(v int) *node {
	i := s.head.level
	p := s.head
	for i > 0 {
		n := p.nexts[i - 1]
		for n != nil && n.v < v {
			p = n
			n = n.nexts[i - 1]
		}
		if n != nil && n.v == v {
			return n
		}
		i --
	}
	return nil
}

func (s *skipList) delete(d *node) {
	i := d.level
	p := s.head
	for i > 0 {
		n := p.nexts[i - 1]
		for n != nil && n.v < d.v {
			p = n
			n = n.nexts[i - 1]
		}
		p.nexts[i - 1] = d.nexts[i - 1]
		i --
	}
}

func (s *skipList) print() {
	p := s.head
	for (p.nexts[0] != nil) {
		fmt.Println(p.nexts[0].v)
		p = p.nexts[0]
	}
}

func main() {
	s := NewSkipList()
	s.insert(8)
	s.insert(5)
	s.insert(3)
	s.insert(7)
	s.insert(4)
	s.insert(9)
	s.insert(100)
	s.insert(101)
	s.insert(55)
	s.insert(20)
	s.insert(18)
	s.insert(11)
	s.insert(15)
	s.insert(33)
	s.print()

	for i := 0; i < 2; i++ {
		n := s.search(7)
		if n != nil {
			fmt.Println("found")
			s.delete(n)
		} else {
			fmt.Println("no found")
		}
	}

	s.print()
}

  

原文地址:https://www.cnblogs.com/yanbiao/p/12588220.html

时间: 2024-08-28 22:23:43

golang 实现跳表skiplist的相关文章

Go语言实现跳表(SkipList)

跳表(skiplist)在redis/levelDB中属于核心数据结构,我简单粗暴的用Golang实现了下. 就我的简单理解来说,就一个普通的链表,在insert时,通过Random_level(),把一层变成很多层, 越上数据越小,跨度越大. 查找时从上往下找,用空间换时间. 记下测试代码: package main import ( "fmt" //"github.com/xclpkg/algorithm" "math/rand" ) fun

存储系统的基本数据结构之一: 跳表 (SkipList)

在接下来的系列文章中,我们将介绍一系列应用于存储以及IO子系统的数据结构.这些数据结构相互关联又有着巨大的区别,希望我们能够不辱使命的将他们分门别类的介绍清楚.本文为第一节,介绍一个简单而又有用的数据结构:跳表 (SkipList) 在对跳表进行讨论之前,我们首先描述一下跳表的核心思想. 跳表(Skip List)是有序线性链表的一种.通常对线性链表进行查找需要遍历,因而不能很好的使用二分查找这样快速的方法(想像一下在链表中定位中间元素的复杂度).为了提高查找速率,我们可以将这些线性链表打散,组

跳表SkipList

原文:http://www.cnblogs.com/xuqiang/archive/2011/05/22/2053516.html 跳表SkipList 1.聊一聊跳表作者的其人其事 2. 言归正传,跳表简介 3. 跳表数据存储模型 4. 跳表的代码实现分析 5. 论文,代码下载及参考资料 <1>. 聊一聊作者的其人其事  跳表是由William Pugh发明.他在 Communications of the ACM June 1990, 33(6) 668-676 发表了Skip lists

跳表SkipList—定义

1.聊一聊跳表作者的其人其事 2. 言归正传,跳表简介 3. 跳表数据存储模型 4. 跳表的代码实现分析 5. 论文,代码下载及参考资料 <1>. 聊一聊作者的其人其事 跳表是由William Pugh发明.他在 Communications of the ACM June 1990, 33(6) 668-676 发表了Skip lists: a probabilistic alternative to balanced trees,在该论文中详细解释了跳表的数据结构和插入删除操作. Will

C语言跳表(skiplist)实现

一.简介 跳表(skiplist)是一个非常优秀的数据结构,实现简单,插入.删除.查找的复杂度均为O(logN).LevelDB的核心数据结构是用跳表实现的,redis的sorted set数据结构也是有跳表实现的.代码在这里:http://flyingsnail.blog.51cto.com/5341669/1020034 二.跳表图解 考虑一个有序表: 从该有序表中搜索元素 < 23, 43, 59 > ,需要比较的次数分别为 < 2, 4, 6 >,总共比较的次数 为 2 +

跳表 SkipList

跳跃表实现简单,空间复杂度和时间复杂度也较好,Redis中使用跳表而不是红黑树. 实现参考了: 跳跃列表 - 维基百科,自由的百科全书 <Redis设计与实现>第五章 跳跃表 Redis源码3.0分支src/t_zset.c等文件 插入时的核心逻辑: 找到插入的位置 随机得到新插入节点的level 处理为了插入当前节点穿过的指针和未穿过的指针的指向和跨度 删除时的核心逻辑: 找到删除的位置 处理要删除的节点穿过的指针和未穿过的指针的指向和跨度 如果可以,减小跳跃表的level 下面两个题可以使

红黑树、B(+)树、跳表、AVL等数据结构,应用场景及分析,以及一些英文缩写

在网上学习了一些材料. 这一篇:https://www.zhihu.com/question/30527705 AVL树:最早的平衡二叉树之一.应用相对其他数据结构比较少.windows对进程地址空间的管理用到了AVL树 红黑树:平衡二叉树,广泛用在C++的STL中.map和set都是用红黑树实现的.我们熟悉的STL的map容器底层是RBtree,当然指的不是unordered_map,后者是hash. B/B+树用在磁盘文件组织 数据索引和数据库索引 Trie树 字典树,用在统计和排序大量字符

K:跳表

??跳表(SkipList)是一种随机化的数据结构,目前在redis和leveldb中都有用到它,它的效率和红黑树以及 AVL 树不相上下,但跳表的原理相当简单,只要你能熟练操作链表, 就能轻松实现一个 SkipList. 考虑一个有序表: 从该有序表中搜索元素 < 23, 43, 59 >,需要比较的次数分别为 < 2, 4, 6 >,总共比较的次数为 2 + 4 + 6 = 12 次. 有没有优化的算法吗?链表是有序的,但不能使用二分查找.类似二叉搜索树,我们把一些节点提取出来

SkipList 跳表

为什么选择跳表 目前经常使用的平衡数据结构有:B树,红黑树,AVL树,Splay Tree, Treep等. 想象一下,给你一张草稿纸,一只笔,一个编辑器,你能立即实现一颗红黑树,或者AVL树 出来吗? 很难吧,这需要时间,要考虑很多细节,要参考一堆算法与数据结构之类的树, 还要参考网上的代码,相当麻烦. 用跳表吧,跳表是一种随机化的数据结构,目前开源软件 Redis 和 LevelDB 都有用到它, 它的效率和红黑树以及 AVL 树不相上下,但跳表的原理相当简单,只要你能熟练操作链表, 就能轻