跳跃表 C#
虽然avl树和红黑树在数据搜索和排序方面都是有效的数据结构,但是都显得特别麻烦,跳跃表就显得特别简单,虽然简单 不影响他性能,在平均情况下,其插入、删除、查找数据时间复杂度都是O(log(N)),其最坏情况下都为O(N)。 跳跃表的构造源于一种用于查找的基础数据结构---链表。跳跃表就是在普通链表的情况下,随机在一些节点上增加几层链,用于指向后面的数据。
普通链表 :
跳跃表:
链表就像走楼梯,普通链表一步一个阶梯,但是跳跃表可以达到一步好多个阶梯。所以效率比普通链表快多了。
跳跃表实现需要两个类:一个节点类和一个跳跃表本身的类。
=代码如果出错,欢迎指出=
节点类代码:
public class SkipNode
{
public int key;
public Object value;
public SkipNode[] link;
public SkipNode(int level,int key , Object Value)
{
this.key=key;
this.value=value;
link=new SkipNode[level];
}
跳跃表类代码:
public class SkipList
{
private int maxLevel;
private int level;
private SkipNode header;
private const int NIL=Int32.MaxValue;
private const int PROB =0.5F;
}
SkipList类的构造器包含两个部分:带单独一个参数的Public构造器,其中此参数是跳跃表内节点的总数量,以及一个完成大部分工作的Private构造器数。
代码如下:
public SkipList(long maxNodes) //把节点总数量传递给构造器方法作为方法内的唯一参数。初始化跳跃表对象工作的,private构造器在调用时会有两个参数
{
this.SkipList2(PROB,(int)(Math.Ceiling(Math.Log(maxNodes)/Math.Log(1/PROB)-1)));
}
private void SkipList2(float probable,int maxLevel) //设置了数据成员的数值,创建了跳跃表的头节点,创建了用于每个节点链的“空”节点,记忆初始化了该元素的链
{
this.proability=probable;
this.maxLevel=maxLevel;
level=0;
header=new SkipNode(maxLevel,0,null);
SkipNode nilElement=new Skip(maxLevel,NIL,null);
for(int i=0;i<=maxLevel-1;i++)
header.link[i]=nilElement;
}
概率方法代码:
private int GenRandomLevel() //随机给链层数
{
int newLevel=0;
Random r= new Random();
int ran=r.Next(0);
while((newLevel<maxLevel)&&ran<provavility))
newLevel++;
return newLevel;
}
插入代码:
public void insert(int key,Object value)
{
SkipNode[] update=new SkipNode[maxLevel];
SkipNode cursor=header;
for( int i=level;i>=level;i--) //从当前最高层到最底层
{
while (cursor.link[i].key<key) //如果比要找的这个数值要小的话,就到指向下一个节点,用update【i】来接收每一层的最后一个节点
cursor=cursor.link[i];
update[i]=cursor;
}
cursor=cursor.link[0];
if (cursor.key=key) //如果存在,那就覆盖
cursor.value=value;
else
{
int newLevel =GenRandomLevel();
if (newLevel>level) //如果随机出来的链层比当前链层高的情况
{
for(int i=level+1;i<=newLevel-1;i++)
update[i]=header;
level=newLevel;
}
cursor = new SkipNode(newLevel,key,Value); // 插入
for(int i=0;i<=newLevel-1;i++) //插入后改变自己的链指向的节点,和前面节点的链指向的节点变成自己
{
cursor.link[i]=update[i].link[i];
update[i].link[i]=cursor;
}
}
}
删除代码:
public void Delete(int key)
{
SkipNode[] update=new SkipNode[maxLevel+1];
SkipNode cursor=header;
for(Int i=level;i>=level;i--)
{
while(cursor.link[i].key<key)
cursor=cursor.link[i];
update[i]=cursor;
}
cursor=cursor.link[0];
if(cursor.key==key)
{
for(int i=0;i<level-1;i++)
if(update[i].link[i]==cursor)
update[i].link[i]=cursor.link[i]; //直接等于要删除节点的后面节点
while((level>0)&&(header.link[level].key==NIL)) //删除当前节点的链层
level--;
}
}
遍历代码:
public Object Search(int key)
{
SkipNode cursor=header;
for(int i=level;i>0;i--)
{
SkipNode nexeElement=cursor.link[i];
while(nextElement.key<key)
{
cursor=nextElement;
nextElement=cursor.link[i];
}
}
cursor=cursor.link[0];
if(cursor.key==key)
return cursor.value;
else
return "Object not found";
}
跳跃表 C#的更多相关文章
- 跳跃表Skip List的原理和实现
>>二分查找和AVL树查找 二分查找要求元素可以随机访问,所以决定了需要把元素存储在连续内存.这样查找确实很快,但是插入和删除元素的时候,为了保证元素的有序性,就需要大量的移动元素了.如果 ...
- 浅析SkipList跳跃表原理及代码实现
本文将总结一种数据结构:跳跃表.前半部分跳跃表性质和操作的介绍直接摘自<让算法的效率跳起来--浅谈“跳跃表”的相关操作及其应用>上海市华东师范大学第二附属中学 魏冉.之后将附上跳跃表的源代 ...
- skip跳跃表的实现
skiplist介绍 跳表(skip List)是一种随机化的数据结构,基于并联的链表,实现简单,插入.删除.查找的复杂度均为O(logN).跳表的具体定义, 跳表是由William Pugh发明的, ...
- 跳跃表Skip List【附java实现】
skip list的原理 Java中的LinkedList是一种常见的链表结构,这种结构支持O(1)的随机插入及随机删除, 但它的查找复杂度比较糟糕,为O(n). 假如我们有一个有序链表如下,如果我们 ...
- skip list跳跃表实现
跳表(skip List)是一种随机化的数据结构,基于并联的链表,实现简单,插入.删除.查找的复杂度均为O(logN).跳表的具体定义,跳表是由William Pugh发明的,这位确实是个大牛,搞出一 ...
- redis skiplist (跳跃表)
redis skiplist (跳跃表) 概述 redis skiplist 是有序的, 按照分值大小排序 节点中存储多个指向其他节点的指针 结构 zskiplist 结构 // 跳跃表 typede ...
- 数据结构与算法(c++)——跳跃表(skip list)
今天要介绍一个这样的数据结构: 单向链接 有序保存 支持添加.删除和检索操作 链表的元素查询接近线性时间 ——跳跃表 Skip List 一.普通链表 对于普通链接来说,越靠前的节点检索的时间花费越低 ...
- 基于跳跃表的 ConcurrentSkipListMap 内部实现(Java 8)
我们知道 HashMap 是一种键值对形式的数据存储容器,但是它有一个缺点是,元素内部无序.由于它内部根据键的 hash 值取模表容量来得到元素的存储位置,所以整体上说 HashMap 是无序的一种容 ...
- redis 系列7 数据结构之跳跃表
一.概述 跳跃表(skiplist)是一种有序数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的.在大部分情况下,跳跃表的效率可以和平衡树(关系型数据库的索引就是平衡树 ...
随机推荐
- 六步实现Spring.NET 与 NHibernate 的整合
最近刚完成一个项目,其中对数据库的架构用到的是Spring.NET 与 NHibernate相结合的产物.对于这两项技术,我自己也不是太熟悉,不过好在网上有很多关于这方面的介绍文档,在这里就不多说了. ...
- 跨服务器的sql使用
由于想从别的服务器上的数据库导入一些数据过来 经网上查阅,得到 select * from openrowset( 'SQLOLEDB', '服务器名字'; '用户名'; '密码',数据库名字.dbo ...
- 【初级坑跳跳跳】[NULLException] findViewById() id 引用错误,导致空指针
在学习Intent页面切换,几个页面切换,导致view id 写错,写成另一个xml里的id去了,导致空指针异常 setContentView(R.layout.activity_second); B ...
- union以及一些扩展
select name,age from Students where Age<3unionselect name ,age from Students where Age >4--两个结 ...
- 写一个Windows上的守护进程(2)单例
写一个Windows上的守护进程(2)单例 上一篇的日志类的实现里有个这: class Singleton<CLoggerImpl> 看名字便知其意--单例.这是一个单例模板类. 一个进程 ...
- My97DatePicker使用的问题
我在iframe中使用My97DatePicker时,发现第一次点击左边的菜单时,在右边的页面可以弹出日期框: 当我第二次点击菜单时,右边的日期文本框却弹出了页面的内容,而不是日期选择框: 首先怀疑是 ...
- MySql5压缩包安装
一. 解压所有文件到一个目录:例如D:\Program Files\mysql-5.6.22-winx64 二. 配置系统的环境变量:在Path路径后追加:;D:\Program Files\mysq ...
- 资源回收 left
select DISTINCT human.tid,log_pv_change.systafftid from human left join human_user on human.tid=huma ...
- Entity Framewor中的 Migration
http://www.entityframeworktutorial.net/code-first/code-based-migration-in-code-first.aspx = Code bas ...
- 2014第7周1Web安全概念学习
晚上没有加班,回来后尝试几个感觉不错的行动:1.列出当天最有意义的五件事:2.靠墙站,纠正自己的姿势同时锻炼眼睛:这两点以后也要坚持成为每天的习惯.然后我又陷入了知乎的各种信息中,一个多小时的时间悄悄 ...