簡體   English   中英

cpp中的跳過列表實現

[英]Skip List implementation in cpp

我正在嘗試在cpp中實現一個跳過列表。 跳過列表有很多版本,但是我特別想實現一個版本,其中每個節點都有一個向右和向下的指針,以形成各個級別的連接列表。 同樣在每個更高級別上,都有一個節點的副本,而不僅僅是一個指針。

我正在提供我現在已實施的代碼。 到目前為止,我僅實現了一個功能,即插入。 但是我遇到了細分錯誤。 我知道我在構造函數,更新或插入函數中的某個地方弄亂了指針。 有人可以幫忙嗎?

class SkipList
{

    private:

        struct node {

            int key;
            int data;
            int level;
            struct node* rgt = nullptr;
            struct node* dwn = nullptr ;

            node(int k, int value, int l):
            key(k), data(value), level(l)
            {}

        };


        //generates the ndde level in tha range [1,maxLevel).
        int randomLevel() const;

        //returns a set of pointers to the location at each node where new links are to be created
        std::vector<node*> update(int searchKey) const ;

        //creates a new node and returns a pointer to it
        static node* makeNode(int key, int val, int level);

        const float probability;
        const int maxLevel;


        // head and tail vectors
        vector<node*> head;
        vector<node*> nil;


    public:

        SkipList();
        ~SkipList();
        void insert(int searchKey, int val);
        void print() const;
};

SkipList::SkipList() :
probability(0.5), maxLevel(16)
{

    int headkey = std::numeric_limits<int>::min();
    int nilkey  = std::numeric_limits<int>::max();

    for(int i = 0; i < maxLevel;i++)
    {
        head[i] = new node(headkey,0,maxLevel-1);
        nil[i] = new node(nilkey,0,maxLevel-1);

        if(i > 0)
        {
            head[i]-> dwn = nil[i-1];
            nil[i] -> dwn = nil[i-1];
        }

        head[i]->rgt = nil[i];
    }

}



void SkipList::insert(int searchKey, int val)
{

    vector <node*> preds = update(searchKey);
    node* temp;

    const int newLevel = randomLevel();

    for(int i = 0; i< newLevel; i++)

    {

        node* ptr = makeNode(searchKey,val, newLevel-1);
        temp = preds[i]->rgt;
        preds[i]->rgt = ptr;
        ptr->rgt = temp;

    }

 }

void SkipList::print() const{

    node* list = head[0]->rgt;
    int lineLength = 0;

    std::cout<<"{";

    while (list->rgt != nil[list->level])
    {
        std::cout<<"value: "<<list->data
            <<", key: "<<list->key
            <<", level: "<<list->level;

        list = list->rgt;

        if(list->rgt != nil[list->level]) std::cout<<" : ";
        if (++lineLength % 2 == 0) std::cout << "\n";
    }

    std::cout << "}\n";

}

int SkipList::randomLevel() const{

    int v = 1;
    while (((double)std::rand() / RAND_MAX) < probability 
    && v < maxLevel)
    {
        v++;
    }
    return v;
}

SkipList::node* SkipList::makeNode(int key, int value, int level){
    return new node(key, value, level);
}

std::vector<SkipList::node*>SkipList::update(int searchKey) const{

    int level = head[0]->level;

    std::vector<node*> result(level,nullptr);

    node* x ;

    for(unsigned int i = level;i-- >0;)
    {
        x = head[i];
        while(x->rgt->key < searchKey)
        {
            x = x->rgt;
        }
        result[i]= x;

    }

    return result;

}

int main()
{

    SkipList s;

    s.insert(5,22);
    s.insert(2,33);
    s.print();

    return 0;

}

您應該在SkipList的ctor中使用push_back方法。 現在您正在創建對象

head[i] = new node(headkey,0,maxLevel-1);

並且您正在嘗試將創建的節點對象分配給由vector::operator[]返回的對象(該對象不存在)。 或者,您可以在進入for循環之前調用vector::resize(maxlevel)方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM