`
田庆阳
  • 浏览: 6235 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

算法导论——跳跃表的实现

阅读更多

在麻省理工的算法导论视频中,已对跳跃表讲述的很清晰,并且国内也有很多文章关于跳跃表的原理讲述的很明白,但是,在实现时,代码都是各种拷贝,看的云里雾里,自己写了一份,供大家参考(共计两个文件),感觉跳跃表实现的关键就是在查找目标元素时,能将“跳”体现处理,有不少网上给的参考代码,没有体现出跳跃的处理:

// skip_list.h

#include <assert.h>
#include <iostream>

const int skip_list_max_level = 32;

class SkipListNode
{
    public:
        SkipListNode(int k = -1, int v = -1) : key(k), value(v)
        {
            for (int uli = 0; uli < skip_list_max_level; ++uli)
            {
                pNext[uli] = NULL;
            }
        }


    public:
        int key;
        int value;
        SkipListNode* pNext[skip_list_max_level];
};

class SkipList
{
    public:
        SkipList()
        {
            init();
        }

        void init();
        int  search(int key);
        bool search(int key, int& value);
        void remove(int key);
        void insert(int key, int value);

        void display_all();
        void display_by_level(int level);

    private:
        int rand_insert_level();


    private:
        int _cur_level;
        SkipListNode* _pHead;
};

 

int SkipList::rand_insert_level()
{
    int level = 1;
    while (rand() % 2 == 1)
    {
        ++level;
    }

    return level;
}

void SkipList::init()
{
    _cur_level = 1;
    _pHead = new SkipListNode();
    assert(NULL != _pHead);

    return;
}

int SkipList::search(int key)
{
    SkipListNode* pcur = _pHead;
    for (int ulj = _cur_level - 1; ulj >= 0; --ulj)
    {
        while (pcur->pNext[ulj] && pcur->pNext[ulj]->key < key)
        {
            pcur = pcur->pNext[ulj];
        }

        if (pcur->pNext[ulj])
        {
            if (pcur->pNext[ulj]->key == key)
            {
                return pcur->pNext[ulj]->value;
            }
        }
    }

    return -1;
}

 

void SkipList::insert(int key, int value)
{
    SkipListNode* insert_pos[skip_list_max_level];
    for (int uli = 0; uli < skip_list_max_level; ++uli)
    {
        insert_pos[uli] = _pHead;
    }

    SkipListNode* pcur = _pHead;
    for (int ulj = _cur_level - 1; ulj >= 0; --ulj)
    {
        while (pcur->pNext[ulj] && pcur->pNext[ulj]->key < key)
        {
            pcur = pcur->pNext[ulj];
        }

        if (pcur->pNext[ulj])
        {
            if (pcur->pNext[ulj]->key == key)
            {
                pcur->pNext[ulj]->value = value;
            }
        }

        insert_pos[ulj] = pcur;
    }

    SkipListNode* pNewElement = new SkipListNode(key, value);
    assert(NULL != pNewElement);

    int rand_level = rand_insert_level();
    for (int ulk = rand_level - 1; ulk >= 0; --ulk)
    {
        pNewElement->pNext[ulk] = insert_pos[ulk]->pNext[ulk];
        insert_pos[ulk]->pNext[ulk] = pNewElement;
    }

    _cur_level = _cur_level > rand_level ? _cur_level : rand_level;
    return;
}

bool SkipList::search(int key, int& value)
{
    SkipListNode* pcur = _pHead;
    for (int ulj = _cur_level - 1; ulj >= 0; --ulj)
    {
        while (pcur->pNext[ulj] && pcur->pNext[ulj]->key < key)
        {
            pcur = pcur->pNext[ulj];
        }

        if (pcur->pNext[ulj])
        {
            if (pcur->pNext[ulj]->key == key)
            {
                value = pcur->pNext[ulj]->value;
                return true;
            }
        }
    }

    return false;
}

 

void SkipList::remove(int key)
{
    SkipListNode* remove_pos[skip_list_max_level];
    for (int uli = 0; uli < skip_list_max_level; ++uli)
    {
        remove_pos[uli] = NULL;
    }

    int rm_level = 0;
    SkipListNode* pcur = _pHead;
    for (int ulj = _cur_level - 1; ulj >= 0; --ulj)
    {
        while (pcur->pNext[ulj] && pcur->pNext[ulj]->key < key)
        {
            pcur = pcur->pNext[ulj];
        }

        if (pcur->pNext[ulj])
        {
            if (pcur->pNext[ulj]->key == key)
            {
                ++rm_level;
                remove_pos[ulj] = pcur->pNext[ulj];
            }
        }
    }

    if (rm_level > 0)
    {
        SkipListNode* pRemove = remove_pos[0]->pNext[0];
        for (int ulk = rm_level - 1; ulk >= 0; --ulk)
        {
            remove_pos[ulk]->pNext[ulk] = remove_pos[ulk]->pNext[ulk]->pNext[ulk];
        }

        delete pRemove;
    }

    int blank_level_count = 0;
    for (int ulm = _cur_level - 1; ulm >= 0; --ulm)
    {
        if (NULL == _pHead->pNext[ulm])
        {
            ++blank_level_count;
        }
    }

    _cur_level -= blank_level_count;
    return;
}

 

void SkipList::display_all()
{
    for (int level = skip_list_max_level - 1; level >= 0; --level)
    {
        std::cout << "current level is " << level << " : ";
        SkipListNode* pcur = _pHead->pNext[level];
        while (pcur)
        {
            std::cout << pcur->key;
            pcur = pcur->pNext[level];
        }
       std::cout << std::endl;
    }

    return;
}

void SkipList::display_by_level(int level)
{
    if (level > skip_list_max_level || level < 0)
    {
        std::cout << "input level is error " << level << std::endl;
        return;
    }

    std::cout << "current level is " << level << " : ";
    SkipListNode* pcur = _pHead->pNext[level];
    while (pcur)
    {
        std::cout << pcur->key;
        pcur = pcur->pNext[level];
    }
    std::cout << std::endl;

    return;
}


//   main.cpp
#include "skip_list.h"

void search_test()
{
    SkipList skip_list;
    skip_list.init();

    for (int uli = 0; uli < 10; ++uli)
    {
        skip_list.insert(uli * 2, uli * 10);
    }
    skip_list.search(2);

    for (int uli = 0; uli < 10; ++uli)
    {  
        skip_list.insert(uli * 2 + 1, uli * 10);
    }
    skip_list.search(3);
    skip_list.search(4);

    return;
}

void remove_test()
{
    SkipList skip_list;
    skip_list.init();

    for (int uli = 0; uli < 10; ++uli)
    {
        skip_list.insert(uli * 2, uli * 10);
    }

    for (int uli = 0; uli < 10; ++uli)
    {
        skip_list.insert(uli * 2 + 1, uli * 10);
    }
    skip_list.display_all();

    for (int uli = 0; uli < 10; ++uli)
    {
        skip_list.remove(rand() % 20);
    }
    skip_list.display_all();

    return;
}

int main()
{
//    search_test();
    remove_test();

    return 0;
}

 

分享到:
评论

相关推荐

    算法导论——所有算法和数据结构的C++实现

    所有代码都是在我学习这本书时亲手敲出来的,并且调试正确了,包括:第三部分到第六部分(即10-26章),外加第七部分31和32章所有的算法和数据结构以及编程习题还有思考题的C++实现源代码; 第一、二部分学习的较早...

    算法导论——算法经典

    算法导论,关于算法最权威最全面最深入的书籍,分享给大伙儿~

    MIT算法导论——算法顶尖经典教材

    通过学习《MIT算法导论》,读者不仅可以掌握各种算法的实现,还能理解算法设计的原则,培养解决问题的思维能力。此外,书中包含的习题和实例有助于巩固所学知识,提升实践能力。无论是对于计算机科学专业的学生,...

    算法导论——《Introduction to Algorithms》

    《算法导论》由Thomas H.Cormen、Charles E.Leiserson、Ronald L.Rivest、Clifford Stein四人合作编著(其中Clifford Stein是第二版开始参与的合著者)。本书的最大特点就是将严谨性和全面性融入在了一起。

    MIT公开课——算法导论教材

    《MIT公开课——算法导论》的讲义部分可能详细解释了这些概念,并通过实例演示了如何实现和分析算法的效率。答案部分则帮助学生检查自我学习的效果,加深对知识的理解。这本教材不仅适合初学者入门,也对有一定经验...

    算法导论——

    算法导论!经典的算法!其中包含很多好思想!学习好算法的利器!

    算法导论 +答案 MIT

    《算法导论》原书名——《Introduction to Algorithms》,是一本十分经典的计算机算法书籍,与高德纳(Donald E.Knuth)的《计算机程序设计艺术》(《The Art Of Computer Programming》)相媲美。 《算法导论》由...

    算法导论中文第三版习题答案

    《算法导论》是计算机科学领域的一本经典著作,它深入浅出地介绍了算法的设计、分析和实现。中文第三版的出版,使得更多的中文读者能够接触到这本权威教材。本书覆盖了从排序和搜索到图算法,再到动态规划和贪心算法...

    算法导论答案第四版英文版

    《算法导论》是计算机科学领域的一本经典著作,它由Thomas H. Cormen、Charles E. Leiserson、Ronald L. Rivest和Clifford Stein四位作者共同撰写,全面深入地介绍了算法的设计、分析以及计算问题的解决方案。这本书...

    算法导论 第三版 中文pdf

    算法导论 第三版 中文pdf

    算法导论中文版——经典

    算法学习必看之作。。。经典之中的经典。。。。。。。。。。。。。。。。。。。。。。。。。。

    算法导论 中英文高清版本

    《算法导论》是一本备受推崇的计算机科学教材,它深入浅出地介绍了算法的设计、分析和实现。这本书由Thomas H. Cormen、Charles E. Leiserson、Ronald L. Rivest和Clifford Stein四位作者共同撰写,是全球范围内...

    算法导论第二十四章答案

    算法导论第二十四章答案 算法导论第二十四章答案 算法导论第二十四章答案

    算法导论(英文原版教材).pdf

    "算法导论(英文原版教材)" 本书《算法导论》(英文原版教材)由 Thomas H. Cormen、Charles E. Leiserson、Ronald L. Rivest 和 Clifford Stein 合著,是一本关于算法的经典教材。本书共分为 34 章,涵盖了算法的...

    算法导论试题及答案

    5. **数据结构**:数组、链表、栈、队列、哈希表、树(二叉树、平衡树如AVL和红黑树)、图等,以及它们在算法实现中的角色。 6. **递归与分治**:递归函数的设计、分治策略的应用,如归并排序、快速排序、Strassen...

    算法导论电子版

    Cormen 算法导论扫描版 清晰 算法入门 经典

    零起点学算法34——继续求多项式

    零起点学算法34——继续求多项式:方法1:输入1个正整数n

    算法导论(英文第四版)非扫描

    - **2.1 插入排序**:通过一个简单的例子介绍了一种基本的排序算法——插入排序。 - **2.2 分析算法**:探讨了如何评估算法的效率,包括时间复杂度和空间复杂度。 - **2.3 设计算法**:讨论了设计高效算法的基本...

    算法导论(原书第3版) 中文完整版带目录

    《算法导论》是计算机科学领域的一本经典著作,它为读者提供了全面而深入的算法理论与实践知识。原书的第三版包含了丰富的更新和扩展,尤其适合对算法有深入研究的学生和专业人士。这本书涵盖了从基础到高级的各种...

Global site tag (gtag.js) - Google Analytics