跳跃表 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)是一种有序数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的.在大部分情况下,跳跃表的效率可以和平衡树(关系型数据库的索引就是平衡树 ...
随机推荐
- CSS3实现图片鼠标悬浮放大效果
.excerpt .focus a img{ -webkit-transition: all ease .3s; transition: all ease .3s }.excerpt .focus a ...
- 11g导入大量包含子分区的数据时表空间不足
问题描述: ORACLE11g使用impdp数据泵导入时遭遇: ORA-01691: Lob 段 ISCS.SYS_LOB0000100750C00045$$ 无法通过 128 (在表空间 RT_DA ...
- Reverse Words in a String (JAVA)
Given an input string, reverse the string word by word. For example,Given s = "the sky is blue& ...
- [转]如何正确清理C盘
转自微软的Answers网站. 以下是推荐使用的方法,安全且不会误删有用的系统文件 1.尽量不要在C盘安装应用软件,在软件安装时,一般可以手动指定安装路径,您可以将软件指定安装到其他盘符. 在使用它们 ...
- 如何让你的SQL运行得更快
人们在使用SQL时往往会陷入一个误区,即太关注于所得的结果是否正确,而忽略了不同的实现方法之间可能存在的性能差异,这种性能差异在大型的或是复杂的数据库环境中(如联机事务处理OLTP或决策支持系统DSS ...
- S - stl 的mapⅠ
先来介绍一下stl中的map这个功能 头文件#include<map> map是STL的一个关联容器,它提供一对一的数据处理能力 就像一个人对应一个编号一样 定义 为 map<in ...
- java基础知识——程序员面试基础
一.面向对象的特征有哪些? 答:①.抽象:抽象是忽略一个主题中与当前目标无关的那些方面,一边更充分的注意与当前目标有关的方面.抽象并不打算了解全面问题,而是选择其中的一部分,暂时不用部分细节.抽象包括 ...
- 第一个XAML程序
创建win8程序的默认Xaml文件是MainPage.Xaml文件,文件的内容如下所示: <Page x:Class="App1.MainPage" xmlns=" ...
- [汇编语言]-第八章 div指令,伪指令dd,dup
1- div除法指令 (1) 除数: 有8位和16位两种,在一个寄存器或内存单元中. (2) 被除数: 默认放在AX和DX或AX中 除数为8位, 被除数为16位, 默认在AX中存放. 除数为16位, ...
- python用法——Mixin
在读werkzeug和flask的源码中,经常能遇到类名中有mixin这个东西.这个东西的用法让我想到了java中的接口名有able的用法.今天我就来看了看这个mixin是什么东西. 学习了pytho ...