跳表

#include<iostream>
#include <math.h>
using namespace std;
 
//E是查询值,K是返回值
template<class E,class K>
class SkipNode{
    public:
        SkipNode(int size){link=new SkipNode<E,K>*[size];}
        ~SkipNode(){delete []link;}
        E data ;
        SkipNode<E,K>**link;//一维指针数组
};
 
 
template<class E,class K>
class SkipList{
    public:
        SkipList(K large,int MaxE = 10000,float p=0.5);
        //MaxE是字典的最大容量
        //一个节点既在i-1级链上又在i级链上的概率为p
        //Large是一个比字典中任意一个数均大的值,尾节点的值为Large
        //0级链上的值(不包括头结点,因其没有值)从左到右顺序排列
        ~SkipList();
        bool Search(const K&k,E&e)const;
        SkipList<E,K>&Insert(const E&e);
        SkipList<E,K>&Delete(const K&k,E&e);
        void Output(ostream& out)const;  
 
        int Level();
        SkipNode<E,K>*SaveSearch(const K&k);
        int MaxLevel;//所允许的最大级数
        int Levels;//当前非空链的个数
        int CutOff;//用于确定级号
        K TailKey;//一个很大的key值
        SkipNode<E,K>*head;//头结点指针
        SkipNode<E,K>*tail;//尾节点指针
        SkipNode<E,K>**last;//指针数组
};
 
 
//重载操作符     
template<class E,class K>  
ostream& operator<<(ostream& out,const SkipList<E,K>&x){    
    x.Output(out);    
    return out;    
}    
//输出该跳表的内容
template<class E,class K>
void SkipList<E,K>::Output(ostream& out)const
{
    SkipNode<E,K> *y=head->link[0];
    for(;y->data!=TailKey;y=y->link[0])
    cout<<y->data<<" ";
    cout<<endl;
}
 
 
template<class E,class K>
SkipList<E,K>::SkipList(K Large,int MaxE,float p){
    CutOff=p*RAND_MAX;
    MaxLevel=ceil(log(MaxE)/log(1/p))-1;
    TailKey = Large;
    //randomize();//初始化随机发生器
    Levels = 0;//对级号进行初始化
 
    //创建头结点、尾节点以及数组last
    head= new SkipNode<E,K>(MaxLevel+1);
    tail= new SkipNode<E,K>(0);
    last= new SkipNode<E,K>*[MaxLevel+1];
    tail->data=Large;
    
    //将所有级都置空且将head指向tail
    for (int i=0;i<=MaxLevel;i++){
        head->link[i]=tail;
    }
}
 
 
//删除所有节点以及数组last
template<class E,class K>
SkipList<E,K>::~SkipList(){
    SkipNode<E,K>*next;
 
    //通过删除0级链来删除所有的节点
    while(head!=tail){
        next=head->link[0];
        delete head;
        head=next;
    }
    delete tail;
    delete []last;
}
 
 
//跳表的操作符重载
class element{
    public:
        operator long()const{return key;}
        element& operator=(long y){
            key = y;
            return *this;
        }
        int data;
        long key;
};
 
 
 
 
 
//搜索与k相匹配的元素,并将找到的元素放入e中
//如果不存在这样的元素则返回false
template<class E,class K>
bool SkipList<E,K>::Search(const K&k,E&e)const{
    if(k>=TailKey)
        return false;
 
    //调整指针p使其恰好指向可能与k匹配的节点的前一个节点
    SkipNode<E,K>*p=head;
    for (int i=Levels;i>=0;i--){
        while(p->link[i]->data<k){
            p=p->link[i];
        }
    }
 
    //检查是否下一个节点拥有关键值k
    e=p->link[0]->data;
    return (e==k);
}
 
//搜索k并且保存最终得到的位置
//在每一级链中搜索
template<class E,class K>
SkipNode<E,K>*SkipList<E,K>::SaveSearch(const K&k){
    SkipNode<E,K>*p=head;
    //调整指针p使其恰好指向可能与k匹配的节点的前一个节点
    for (int i=Levels;i>=0;i--){
        while(p->link[i]->data<k)
            p=p->link[i];
        last[i]=p;
    }
    return (p->link[0]);
}
 
//产生一个随机级号<=MaxLevel
template<class E,class K>
int SkipList<E,K>::Level(){
    int lev = 0;
    while(rand()<=CutOff)
        lev++;
    return (lev<=MaxLevel)?lev:MaxLevel;
}
 
class BadInput{
    public:
        BadInput(){
            cout<<"Bad Input!"<<endl;
        }
};
 
 
//若不存在重复则插入e
template<class E,class K>
SkipList<E,K>& SkipList<E,K>::Insert(const E&e){
    K k = e;
    if(k>=TailKey)
        throw BadInput();//关键值太大了
    
    //检验是否重复
    SkipNode<E,K>*p=SaveSearch(k);
    if(p->data==e)
        throw BadInput();//关键值重复
 
    //不重复则为新节点创建级号
    int lev = Level();
    //fix level to be <=Levels+1
    if (lev>Levels)
    {
        lev=++Levels;
        last[lev]=head;
    }
 
    //产生新节点并且将其插入在p之后
    SkipNode<E,K>*y = new SkipNode<E,K>(lev+1);
    y->data=e;
    for (int i=0;i<=lev;i++){
        //插入到第i级链
        y->link[i]=last[i]->link[i];
        last[i]->link[i]=y;
    }
    return *this;
}
 
//从跳表中删除与k相匹配的元素并将其放到e
//如果不存在则引发异常BadInput
template<class E,class K>
SkipList<E,K>& SkipList<E,K>::Delete(const K&k,E&e){
    if(k>=TailKey)
        throw BadInput();//关键值太大
    
    //检查是否存在与k相匹配的元素
    SkipNode<E,K>*p=SaveSearch(k);
    if(p->data!=k)
        throw BadInput();//不存在
    
    //从跳表中删除节点
    for (int i=0;i<=Levels&&last[i]->link[i]==p;i++)
        last[i]->link=p->link[i];
 
    //修改级数
    while(Levels>0&&head->link[Levels]==tail)
        Levels--;
 
    e=p->data;
    delete p;
    return *this;
}
 
 
void main(){
    SkipList<long,float>mySkip(1000);
    mySkip.Insert(100);
    mySkip.Insert(123);
    mySkip.Insert(12.13);
    mySkip.Insert(10.30);
    mySkip.Insert(124);
    cout<<"CutOff:"<<mySkip.CutOff<<endl;
    cout<<"MaxLevel:"<<mySkip.MaxLevel<<endl;
    cout<<"Level:"<<mySkip.Level()<<endl;
    cout<<"tail:"<<mySkip.tail<<endl;
    cout<<"TailKey:"<<mySkip.TailKey<<endl;
    cout<<mySkip<<endl;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值