跳表的实现-c++版

#include <iostream>
#include <stdlib.h>
#include <random>
using namespace std;

//跳表:有序
//跳表的首结点不存放任何值得虚拟节点

const int MAX_LEVEL=32;
const double P=0.25;



class SkipList
{
//节点
typedef struct Node 
{
    int key_;
    string value_;
    int validlevel_;
    Node *nexts[MAX_LEVEL];
    Node()
    {
        for(int i=0;i<MAX_LEVEL;++i)
        {
           nexts[i]=NULL;
        }
    }
    Node(int key,string value,int level=MAX_LEVEL)
    :key_(key)
    ,validlevel_(level)
    {
        value_=value;
        for(int i=0;i<level;++i)
        {
           nexts[i]=NULL;
        } 
    }
}Node;



private:
    int size_;
    //不存放k-v
    Node *firstNode_;

    //有效得层
    int validlevel_;
public:
    SkipList()
    {
        size_=0;
        validlevel_=-1;
        firstNode_=new Node();  
    }
    int size() const { return size_;}
    bool isEmpty() { return size_==0;}

    //返回之前的value值
    string  insert(int key,string value)
    {
        Node *node=firstNode_;
        Node *prevs[validlevel_];
        for(int i=validlevel_-1;i>=0;--i)
        {
            while((nullptr!=node->nexts[i])&&key<node->nexts[i]->key_)
            {
                //这边指当前层得下一个节点
                node=node->nexts[i];
            }
            prevs[i]=node;
        }
        if((NULL!=node->nexts[0])&&(node->nexts[0]->key_==key))
        {
                string oldvalue=node->nexts[0]->value_;
                node->nexts[0]->value_=value;
                return oldvalue;
        }
        //新节点的层数
        int newLevel=randomLevel();

        //添加新节点
        //cout<<"ff"<<endl;
        Node * newNode=new Node(key,value,newLevel);
      //  cout<<"eee"<<endl;
        for(int i=0;i<newLevel;++i)
        {
            if(i>=validlevel_)
            {
                firstNode_->nexts[i]=newNode;
            }else{
            newNode->nexts[i]=prevs[i]->nexts[i];
            prevs[i]->nexts[i]=newNode; 
            }
        }
        size_++;
        validlevel_=max(validlevel_,newLevel);
        return " ";
    }
    //传递一个key返回对应的value值
    string get(int key)
    {

        Node *node=firstNode_;

        //firstNode_->nexts[0]:代表下个节点
        //当前得key 小于等于传入得key
        //node->nexts[i]->key_:拿到是下一个节点
        for(int i=validlevel_-1;i>=0;--i)
        {
            while((nullptr!=node->nexts[i])&&key<node->nexts[i]->key_)
            {
                //这边指当前层得下一个节点
                node=node->nexts[i];
            }
        }

        /**
        * node是小于v的节点, node的下一个节点就等于或大于v的节点
        */ 
        if((NULL!=node->nexts[0])&&(node->nexts[0]->key_==key))
        {
            cout <<"key:"<<key<<"value:"<<node->nexts[0]->value_<<endl;
            return node->nexts[0]->value_;
        }
        return "nullptr";
    }
    //返回删除的key的value值
    string remove(int key)
    {
        Node *node=firstNode_;
        Node *prevs[validlevel_];
        bool exist=false;
        for(int i=validlevel_-1;i>=0;--i)
        {
              int cmp=-1;
            while((nullptr!=node->nexts[i])&&(cmp=key<=node->nexts[i]->key_))
            {
                //这边指当前层得下一个节点
                node=node->nexts[i];
            }
            prevs[i]=node;
            if(cmp==1) exist=true;
        }
        if(!exist) return nullptr;

        Node  * removeNode=node->nexts[0];

        for(int i=0;i<removeNode->validlevel_;i++)
        {
            prevs[i]->nexts[i]=removeNode->nexts[i];
        }
        //更新跳表的层数
        int newLevel=validlevel_;

        while (--newLevel>=0 && firstNode_->nexts[newLevel]==nullptr)
        {
            validlevel_=newLevel;
        }
        size_--;
        delete removeNode;
        return node->nexts[0]->value_;
    }


    int randomLevel()
    {
    int level=1;
    double number=rand()%1000/1000.00;
    while( number< 0.625 &&level<MAX_LEVEL)
    {
        level++;
        number=rand()%1000/1000.00;
    }
        return level;
    }

    void PrintAll()
    {
        Node *lpNode=firstNode_;
        while(NULL!=lpNode->nexts[0]){
        std::cout<<"key: "<<lpNode->nexts[0]->key_<<" value: " <<lpNode->nexts[0]->value_<<" current level: "<<lpNode->nexts[0]->validlevel_<<endl;
        lpNode=lpNode->nexts[0];
    } 
    }
};


int main()
{
    SkipList templist;
    //insert
   for(int i=0;i<10;++i)
   {
        string value="test: ";
        value +=i+'0';
        //cout<<"value:"<<value<<endl;
       templist.insert(i,value);
   }
   //打印
   templist.PrintAll();

    //get
    cout<<"get:"<<templist.get(1)<<endl;
    cout<<"get:"<<templist.get(20)<<endl;

    //update
    cout<<"update:"<<templist.insert(5,"zkm20")<<endl;
    cout<<"get:"<<templist.get(5)<<endl;

    //delete
    cout<<"delet:"<<templist.remove(3)<<endl;
    cout<<"size:"<<templist.size()<<endl;


    templist.PrintAll();





    return 0;
}











评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值