我读到了关于互联网上的跳过列表,我只是想知道它如何使用不同的数据结构和所有。但我真的想用双链表实现跳转列表,因为我想在插入时对双向链表进行排序。意味着当元素插入时,它应该仅以排序的方式插入。
这里我实现了以排序方式在双向链表中插入数据的方法,但是当元素数量非常大时,这需要很长时间来插入数据并按排序方式生成列表。
请告诉我如何在现有功能中添加跳过列表Algo或者我必须重写整个事情?任何有关实施的帮助都将受到赞赏
这是代码:
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);
}
}
}
答案 0 :(得分:1)
跳过列表的优点在于它对数据项进行排序,并提供o(log n)插入和删除时间复杂度。为了使其更容易理解,想象一下您的链表有快捷方式或锚点,这样您就不必遍历整个列表来找到插入项目的位置。您只需按照锚点,因此它是一个带有快速访问锚点的双链表。
至于实现,如果您不打算使用跳过列表进行多线程访问,那么实现起来就变得微不足道了。没有理由将跳过列表与双链表组合,但您可以将跳转列表实现为双链表
看看 http://www.sanfoundry.com/cpp-program-implement-skip-list/
答案 1 :(得分: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