zoukankan      html  css  js  c++  java
  • 跳跃表 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";

    }

    There are two ways of constructing a software design.One is to make it so simple that there are obviously no deficiencies;the other is to make it so complicated that there are no obvious deficiencies.
  • 相关阅读:
    Android 编程下 Eclipse 恢复被删除的文件
    Android 编程下背景图片适配工具类
    Android 编程下 Managing Your App's Memory
    Android 编程下代码之(QQ消息列表滑动删除)
    Android 编程下 Canvas and Drawables
    Android 编程下 AlarmManager
    Android 编程下去除 ListView 上下边界蓝色或黄色阴影
    Java 编程下字符串的 16 位、32位 MD5 加密
    C#枚举类型和int类型相互转换
    MVC和普通三层架构的区别
  • 原文地址:https://www.cnblogs.com/yuanjunqq/p/5736234.html
Copyright © 2011-2022 走看看