2

我在互联网上阅读了跳过列表,我只是了解它如何与不同的数据结构和所有数据一起工作。但我真的想用双向链表实现跳过列表,因为我想在插入时对双向链表进行排序。意味着当元素插入时,它应该仅以排序方式插入。

在这里,我实现了以排序方式在双向链表中插入数据的方法,但是当元素数量非常大时,插入数据并以排序方式制作列表需要很长时间。

请告诉我如何在现有函数中添加跳过列表算法,或者我必须重新重写整个内容?任何有关实施的帮助将不胜感激

这是代码:

void DoubleList::addSorted(int value)
{
    IDoubleNode * tempNode = new DoubleNode();
    tempNode->setValue(value);
    // if double link list is empty 
    if(getHead() == NULL)
    {
        // temp node already has NULL value in next and prev.
        setHead(tempNode);
        setTail(tempNode);
    }
    else if(value <= getHead()->getValue())
    {
        tempNode->setNext(getHead());// set tempnode next as current head.
        tempNode->setPrev(getHead()->getPrev()); // set previous
        getHead()->setPrev(tempNode); // set previous pointer of head to tempnode which we just inserted
        setHead(tempNode); // set head
        getHead()->setPrev(NULL);// for safer side. we already done this.
    }
    else
    {
        int found = 0;
        IDoubleNode *currNode = getHead();
        while(currNode->getNext() != NULL && found == 0)
        {
            if(currNode->getNext()->getValue() > tempNode->getValue())
            {
                found = 1;
            }
            else
            {
                currNode = currNode->getNext();
            }
        }
        if(found)
        {
            tempNode->setNext(currNode->getNext());
            currNode->getNext()->setPrev(tempNode);
            currNode->setNext(tempNode);
            tempNode->setPrev(currNode);
        }
        else
        {
            currNode->setNext(tempNode);
            tempNode->setPrev(currNode);
            tempNode->setNext(NULL);
            setTail(tempNode);
        }
    }
}
4

2 回答 2

1

我希望这可以帮助你。

#ifndef SkipList_h
#define SkipList_h
///////////////////////////////////////////////////////////////////////////////

template<typename K, typename V, int MAXLEVEL>
class SkipListNode
{

public:
    SkipListNode()
    {
        for(int i=1; i<=MAXLEVEL;i++){
            next[i] = nullptr;
            prev[i] = nullptr;
        }
    }

    SkipListNode(K searchKey):key(searchKey)
    {
        for(int i=1; i<=MAXLEVEL;i++){
            next[i] = nullptr;
            prev[i] = nullptr;
        }
    }

    SkipListNode(K searchKey, V val):key(searchKey),value(val)
    {
        for(int i=1; i<=MAXLEVEL;i++){
            next[i] = nullptr;
            prev[i] = nullptr;
        }
    }

    // custom memory management
   // static void * operator new(size_t size);

  //  static void operator delete( void *deadObject, size_t size );


    K key;
    V value;
    SkipListNode<K, V, MAXLEVEL>* next[MAXLEVEL+1];
    SkipListNode<K, V, MAXLEVEL>* prev[MAXLEVEL+1];
private:
   // static MemoryPool<SkipListNode> memPool; // memory pool for SkipListNode
};

// template<typename K, typename V, int MAXLEVEL>
// MemoryPool< SkipListNode<K, V, MAXLEVEL> > SkipListNode<K, V, MAXLEVEL>::memPool;

// template<typename K, typename V, int MAXLEVEL>
// inline void * SkipListNode<K, V, MAXLEVEL>::operator new ( size_t size )
// {
//     return memPool.allocate();
// }

// template<typename K, typename V, int MAXLEVEL>
// inline void SkipListNode<K, V, MAXLEVEL>::operator delete( void *p, size_t size )
 //{
 //    memPool.deallocate( static_cast<SkipListNode<K, V, MAXLEVEL> *>(p) );
 //}


///////////////////////////////////////////////////////////////////////////////

template<typename K, typename V, int MAXLEVEL = 16>
class SkipList
{
public:
    typedef K keyType;
    typedef V ValueType;
    typedef SkipListNode<K, V, MAXLEVEL> NodeType;
    const int maxLevel;

    SkipList(K min_key, K max_key)
                                :pHeader(nullptr), pTail(nullptr),
                                maxCurrLevel(1), maxLevel(MAXLEVEL),
                                minKey(min_key), maxKey(max_key)
    {
        pHeader = new NodeType(minKey);
        pTail = new NodeType(maxKey);

        for( int i = 1; i<=MAXLEVEL; i++){
            pHeader->next[i] = pTail;
            pTail->prev[i] = pHeader;
        }
    }

    virtual ~SkipList()
    {

        delete pHeader;
        delete pTail;
    }

    void removeAll()
    {
        NodeType* curNode = pHeader->next[1];
        while(curNode != pTail){
            NodeType* temp = curNode;
            curNode = curNode->next[1];
            delete temp;
        }
    }

    std::string printList()
    {
        std::stringstream sstr;
        NodeType* currNode = pHeader->next[1];
        while ( currNode != pTail ) {
            sstr << "(" << currNode->key << "," << currNode->value << ")" << std::endl;
            currNode = currNode->next[1];
        }
        return sstr.str();
    }

    NodeType* insert( K searchKey, V newValue );

    void removeKey( K searchKey );
    void removeKey( NodeType* curNode );

    NodeType* search(const K& key, NodeType** prev   );

private:
    K minKey;
    K maxKey;
    int maxCurrLevel;
    SkipListNode<K, V, MAXLEVEL>* pHeader;
    SkipListNode<K, V, MAXLEVEL>* pTail;

    double uniformRandom()
    {
        return rand() / double(RAND_MAX);
    }

    int randomLevel() {
        int level = 1;
        double p = 0.5;
        while ( uniformRandom() < p && level < MAXLEVEL ) {
            level++;
        }
        return level;
    }
};

template<typename K, typename V, int MAXLEVEL>
typename SkipList<K, V, MAXLEVEL>::NodeType* SkipList<K, V, MAXLEVEL>::search(const K& searchKey, NodeType** prev )
{
    NodeType* currNode = nullptr;

    currNode = pHeader;
    for (int level=maxCurrLevel; level>=1; level--) {
        // Start our search at previous level's predecessor

        while (currNode->next[level]->key < searchKey) {
            currNode = currNode->next[level];

        }
        if ( prev != nullptr) {
            prev[level] = currNode;
        }

        //currNode = currNode->next[level];
        /*
        if ( next != nullptr) {
            next[level] = currNode;
        }*/
    }

    currNode = currNode->next[1];
    return currNode;
}

template<typename K, typename V, int MAXLEVEL>
typename SkipList<K, V, MAXLEVEL>::NodeType*  SkipList<K, V, MAXLEVEL>::insert( K searchKey, V newValue )
{
    SkipListNode<K, V, MAXLEVEL>** next = nullptr;
    SkipListNode<K, V, MAXLEVEL>* prev[MAXLEVEL];

    auto foundNode = search(searchKey, prev);


    int newLevel = randomLevel();
    //std::cout<< "Level: "<<newLevel<< std::endl;

    if ( newLevel > maxCurrLevel ) {
        for ( int level = maxCurrLevel+1; level <= newLevel; level++ ) {
            prev[level] = pHeader;
        }

        maxCurrLevel = newLevel;
    }

    NodeType* curNode = new NodeType(searchKey, newValue);

    for ( int level = 1; level<=maxCurrLevel; level++ ) {
        curNode->next[level] = prev[level]->next[level];
        curNode->prev[level] = prev[level];
        prev[level]->next[level]->prev[level] = curNode;
        prev[level]->next[level] = curNode;
    }
    return curNode;
}

template<typename K, typename V, int MAXLEVEL>
void SkipList<K, V, MAXLEVEL>::removeKey( K searchKey)
{

    SkipListNode<K, V, MAXLEVEL>** prev1 = nullptr;

    auto curNode = search(searchKey, prev1);


    //std::cout<<curNode <<" -> "<< curNode->key<< std::endl;
    if ( curNode && curNode->key == searchKey ) {

        auto prev = curNode->prev;

        for ( int level = 1; level<=maxCurrLevel; level++ ) {

            if ( prev[level]->next[level] != curNode ) {
                break;
            }

            prev[level]->next[level] = curNode->next[level];
            curNode->next[level]->prev[level] = prev[level];
        }

        delete curNode;

        while ( maxCurrLevel > 1 && pHeader->next[maxCurrLevel] == pTail) {
            maxCurrLevel--;
        }

        //std::cout << "maxCurrLevel: "<<maxCurrLevel<<std::endl;
    }

}


template<typename K, typename V, int MAXLEVEL>
void SkipList<K, V, MAXLEVEL>::removeKey( typename SkipList<K, V, MAXLEVEL>::NodeType* curNode )
{
    if ( curNode && curNode == curNode->next[1]->prev[1] && curNode == curNode->prev[1]->next[1] ) {
       // std::cout<<curNode <<" -> "<< curNode->key<< std::endl;

        auto prev = curNode->prev;

        for ( int level = 1; level<=maxCurrLevel; level++ ) {

            if ( prev[level]->next[level] != curNode ) {
                break;
            }

            prev[level]->next[level] = curNode->next[level];
            curNode->next[level]->prev[level] = prev[level];
        }

        delete curNode;

        while ( maxCurrLevel > 1 && pHeader->next[maxCurrLevel] == pTail ) {
            maxCurrLevel--;
        }
    }
}


#endif
于 2015-02-24T17:32:37.363 回答
1

跳过列表的美妙之处在于它对数据项进行排序,并且还提供了 o(log n) 的插入和删除时间复杂度。为了使它更容易理解,假设您的链表有捷径或锚点,这样您就不必遍历整个列表来找到插入项目的位置。您只需跟随锚点,因此它是一个具有快速访问锚点的双链表。

至于实现,如果您不打算将跳过列表用于多线程访问,那么实现起来就变得微不足道了。没有理由将跳过列表与双链表结合起来,但您可以将跳过列表实现为双链表

看看 http://www.sanfoundry.com/cpp-program-implement-skip-list/

于 2015-02-14T16:42:05.180 回答