zoukankan      html  css  js  c++  java
  • SkipList算法实现

    SkipList是一种快速查找链表,链表元素的是有序的。由W.Pugh发明于1989年。
    其算法复杂度如下:

          Average    Worst case
    Space    O(n)      O(n log n)
    Search   O(log n)    O(n)
    Insert    O(log n)    O(n)
    Delete    O(log n)    O(n)

    (图片来源于WiKi)

    均算法复杂度不亚于AVL和红黑树。其数据结构和操作也简单。AVL树和红黑树为保
    持平衡,维护树的平衡代价高。

    SkipList 现用于Redis,LevelDB等开源项目, 维基百科可以看它到很多应用场景。

    根据W.Pugh的论文,其算法实现如下:

    
    
    #include <cstdio>
    #include <iostream>
    #include
    <cstdlib> #include <random> using namespace std; #define MaxLevel 5 typedef struct SkipListNode { int value; int key; int level; SkipListNode* forward[MaxLevel]; } SkipListNode; typedef struct SkipList { SkipListNode* head; int level; int length; } SkipList; SkipListNode* makeNode(int level, int key, int value) { SkipListNode* pNode = (SkipListNode *)malloc(sizeof(SkipListNode)); if (!pNode) { return NULL; } pNode->key = key; pNode->value = value; pNode->level = level; for (int i = 0; i < MaxLevel; ++i) pNode->forward[i] = NULL; return pNode; } void initSkipList(SkipList *pSkipList) { if (!pSkipList) return; SkipListNode* head = makeNode(0, 0, 0); if (!head) return; pSkipList->head = head; pSkipList->length = 0; pSkipList->level = 1; for (int i = 0; i < MaxLevel; i++) pSkipList->head->forward[i] = NULL; } int randomLevel() { int newLevel = 1; while ((rand() & 0xFFFF) < (0.4 * 0xFFFF)) ++newLevel; return newLevel < MaxLevel ? newLevel : MaxLevel; }
    bool insertNode(SkipList *pSkipList, int searchKey, int newValue) { SkipListNode* update[MaxLevel]; if (!pSkipList) return false; SkipListNode* pNode = pSkipList->head; if (!pNode) { return false; } for (int i = pSkipList->level - 1; i >= 0; i--) { while (pNode->forward[i] && pNode->forward[i]->key < searchKey) pNode = pNode->forward[i]; // pNode->key < searchKey < pNode->forward[i]->key update[i] = pNode; } pNode = pNode->forward[0]; if (pNode && pNode->key == searchKey) { pNode->value = newValue; } else { int level = randomLevel(); if (level > pSkipList->level) { for (int i = pSkipList->level; i < level; i++) { update[i] = pSkipList->head; } pSkipList->level = level; } pNode = makeNode(level, searchKey, newValue); if (!pNode) { return false; } for (int i = 0; i < pSkipList->level; ++i) { pNode->forward[i] = update[i]->forward[i]; update[i]->forward[i] = pNode; } pSkipList->length++; } return true; } SkipListNode* searchNode(SkipList *pSkipList, int searchKey) { if (!pSkipList) return NULL; SkipListNode *pNode = pSkipList->head; if (!pNode) return NULL; for (int i = pSkipList->level - 1; i >= 0; --i) { while (pNode->forward[i] && pNode->forward[i]->key < searchKey) pNode = pNode->forward[i]; } pNode = pNode->forward[0]; if (pNode && pNode->key == searchKey) return pNode; return NULL; } bool deleteNode(SkipList* pSkipList, int searchKey) { if (!pSkipList) return false; SkipListNode *pNode = pSkipList->head; SkipListNode *update[MaxLevel]; for (int i = pSkipList->level - 1; i >= 0; i--) { while (pNode->forward[i] && pNode->forward[i]->key < searchKey) { pNode = pNode->forward[i]; } update[i] = pNode; } pNode = pNode->forward[0]; if (pNode && pNode->key == searchKey) { for (int i = 0; i < pSkipList->level; ++i) { if (update[i] && update[i]->forward[i] != pNode) { break; } update[i]->forward[i] = pNode->forward[i]; } free(pNode); while (pSkipList->level > 1 && pSkipList->head->forward[pSkipList->level - 1] == NULL) { pSkipList->level--; }
    pSkipList->length--;
    return true; } return false; } void travelList(SkipList* pSkipList) { SkipListNode* pNode = pSkipList->head; if (!pNode) return; while (pNode->forward[0]) { cout << pNode->forward[0]->value << " " << pNode->forward[0]->level << endl; pNode = pNode->forward[0]; } } int main() { SkipList list; initSkipList(&list); insertNode(&list, 10, 10); insertNode(&list, 2, 2); insertNode(&list, 5, 5); travelList(&list); SkipListNode* pNode = searchNode(&list, 2); cout << pNode->value << endl; pNode = searchNode(&list, 10); cout << pNode->value << endl; cout << "----" << endl; deleteNode(&list, 2); travelList(&list); cout << "----" << endl; deleteNode(&list, 10); travelList(&list); cout << "----" << endl; deleteNode(&list, 7); travelList(&list); return 0; }
  • 相关阅读:
    PHP 使用 GET 传递数组变量
    Java实现 蓝桥杯 算法训练 数据交换
    Java实现 蓝桥杯 算法训练 数据交换
    Java实现 蓝桥杯 算法训练 数据交换
    Java实现 蓝桥杯 算法训练 景点游览
    Java实现 蓝桥杯 算法训练 景点游览
    Java实现 蓝桥杯 算法训练 景点游览
    Java实现 蓝桥杯 算法训练 二进制数数
    Java实现 蓝桥杯 算法训练 二进制数数
    Java实现 蓝桥杯 算法训练 二进制数数
  • 原文地址:https://www.cnblogs.com/zhuangzebo/p/4365123.html
Copyright © 2011-2022 走看看