Quicksort在双重链表上

时间:2015-12-01 17:05:53

标签: c++ list sorting queue quicksort

大家好我试图使用互联网上发现的alghoritm在我的调度程序代码中构建quicksort。我的问题是,在代码的某些时候,我得到了关于getPrev的访问冲突,可能它指向null但是我被卡住了,并且不知道如何让它工作。感谢任何一点帮助,或者至少建议我去哪个方向。我已经花了几个小时,它没有任何效果。

#include <iostream>
using namespace std;
class Node
{
public:

Node(int value, Node* nextptr = nullptr, Node* prevptr = nullptr, int     currentpriority = 0)
{
    this->value = value;
    next = nextptr;
    prev = prevptr;
    priority = currentpriority;

}

int getVal(void)
{
    return value;
}

Node* getNext(void)
{
    return next;
}

Node* getPrev(void)
{
    return prev;
}

void setVal(int value)
{
    this->value = value;
}

void setPrev(Node* prevptr)
{
    prev = prevptr;
};

void setNext(Node* nextptr)
{
    next = nextptr;
}

int getPriority(void)
{
    return priority;
}

void setPriority(int priority)
{
    this->priority = priority;
}

private:
Node* next;
Node* prev;
int priority;
int value;
};

class Stack
{
public:
Stack(void)
{
    top = nullptr;
}


~Stack(void)
{
    while (NodePop() != nullptr);
}

void Push(int value)
{
    Node* tmp = new Node(value, top);
    top = tmp;
}

Node* NodePop(void)
{
    Node* tmp = top;
    if (top != nullptr) top = top->getNext();
    return tmp;
}

int Pop(void)
{
    Node* tmp = NodePop();
    int ret = 0;
    if (tmp != nullptr)
    {
        ret = tmp->getVal();
    }

    else
    {
        throw "Stack Empty";
    }
    delete tmp;
    return ret;
}

private:

Node* top;
};

class Queue
{
public:
Queue(void)
{
    back = front = nullptr;
}

~Queue(void)
{
    while (NodeDequeue() != nullptr);
}

void Enqueue(int i, int priority = 0)
{
    Node* tmp = new Node(i, back, nullptr, priority);
    back = tmp;
    if (front == nullptr) front = back;
    else
    {
        tmp = back->getNext();
        tmp->setPrev(back);
    }
}

int Dequeue(void)
{
    Node* tmp = NodeDequeue();
    int ret = 0;
    if (tmp != nullptr)
    {
        ret = tmp->getVal();
    }
    else
    {
        throw "Queue Empty";
    }
    if (front == nullptr) back = front; // queue now empty
    delete tmp;
    return ret;
}

protected:

Node* back;
Node* front;

private:

virtual Node* NodeDequeue(void)
{
    Node* tmp = front;
    if (front != nullptr)
    {
        front = front->getPrev();
        if (front != nullptr) front->setNext(nullptr);
    }
    return tmp;
}
};


class Scheduler : public Queue
{

public:
Node*getTail_Dll(Node*Head)
{
    if (Head != NULL)
    {
        while (Head->getNext() != NULL)
            Head = Head->getNext();
    }

    return Head;
}




 void partition_QuickSort_Dll(Node*Head, Node*Tail)
{
Node* NewTail=NULL,*Curr = Head, *Pivot = Tail;

    while (Curr != Pivot)
    {
        if ((Curr->getVal()) > (Pivot->getVal()))
        {
            if (Curr->getPrev() != NULL)
                Curr->getPrev()->setNext(Curr->getNext());
            if (Curr->getNext() != NULL)
                Curr->getNext()->setPrev(Curr->getPrev());

            NewTail = Curr;
            Curr = Curr->getNext();
            if (Curr->getPrev() == NULL)
                Head = Curr;

            NewTail->setPrev(Tail);
            NewTail->setNext(NULL);
            Tail->setNext(  NewTail);
        }
        else
            Curr = Curr->getNext();
    }

    if (Pivot->getPrev() != NULL)
        Pivot->getPrev()->setNext(NULL);

    if (Pivot->getNext() != NULL)
        Pivot->getNext()->setPrev(NULL);
}

 void quickSortList_Recur_Dll(Node*Head, Node*Tail)
{
    Node*Pivot = Tail;

    if ((Head != NULL) && (Tail != NULL) && (Head != Tail))
    {
        /* partition */
        partition_QuickSort_Dll(Head, Tail);
        /* sort left part */
        quickSortList_Recur_Dll(Head, (Pivot->getPrev()));
        /* sort right part */
            quickSortList_Recur_Dll(Pivot->getNext(), Tail);

        /* connect pivot to left & right parts */
        if (Pivot->getPrev() != NULL)
            Pivot->getPrev()->setNext(Pivot);

        if (Pivot->getNext() != NULL)
            Pivot->getNext()->setPrev( Pivot);  
    }
}

void quickSortList_Dll(Node*Head)
{
    Node*Tail = getTail_Dll(Head);

    if (Head != NULL)
        quickSortList_Recur_Dll(Head, Tail);
}
/*Node* split()
{

    Node *singleJump = back, *doubleJump = back;
    while (singleJump->getNext() && doubleJump->getNext()->getNext())
    {
        doubleJump = doubleJump->getNext()->getNext();
        singleJump = singleJump->getNext();
    }
    Node *temp = singleJump->getNext();
    singleJump->getNext()->setNext(nullptr);
    return temp;
}
*/


/*void antiBlock()
{
    cycle++;
    if (cycle == 5)
    {
        Node* temp = split();
        while (temp != front)
        {
            if (temp->getPriority() < 10)

                temp->setPriority(temp->getPriority() + 1);

        }
        cycle = 0;
    }
}*/
Node* NodeDequeue(void)
{
    Node* tmp = front;

    //antiBlock();
    quickSortList_Dll(back);
    if (front != nullptr)
    {
        front = front->getPrev();
        if (front != nullptr) front->setNext(nullptr);
    }
    return tmp;
}

};



int main()
{

Scheduler* s = new Scheduler;
s->Enqueue(11, 5);
s->Enqueue(2, 6);
s->Enqueue(3, 1);
s->Enqueue(40, 8);
s->Enqueue(15, 9);
s->Enqueue(6, 10);
//s->Enqueue(67, 6);
//s->Enqueue(78, 3);
//s->Enqueue(529, 2);
//s->Enqueue(110, 7);
//s->Enqueue(211, 4);
//s->Enqueue(312, 8);
//s->Enqueue(413, 3);
//s->Enqueue(154, 6);
//s->Enqueue(135, 2);
//s->Enqueue(116, 7);

    for (int i = 0; i < 6; i++)
    cout << s->Dequeue() << endl;


return 0;


};

2 个答案:

答案 0 :(得分:0)

您是否需要使用quicksort(不是列表&#34;友好&#34;)?如果没有,请使用自下而上的合并排序与指向列表的第一个节点的指针数组。它是一种旧算法,但出于某种原因,它并不为人所知。它只使用前向(下一个)指针和合并两个已经排序的列表的典型MergeLists(),因此它的列表&#34;友好&#34;。

示例模式,第一个节点存储在数组[0]中。第二个节点与array [0]合并以创建一个大小为2的列表并存储在array [1]中(array [0]被清除)。两个节点之后,大小为2的列表与array [1]合并以创建大小为4的列表并存储在array [2](array [0],array [1]已清除)中。 array [30]包含一个大小为10亿(2 ^ 30)的列表。 array [31]列表大小不受限制,一次合并10亿个节点。因此,32的数组大小是过度的,但是占用的空间很小,你也可以使用它。

维基文章:

http://en.wikipedia.org/wiki/Merge_sort#Bottom-up_implementation_using_lists

答案 1 :(得分:0)

NodeDequeue中,我认为您在第一个getPrev上呼叫Node。第一个节点之前的节点应始终为null。如果您要删除第一个节点,则应将first设置为first->next,然后将first->prev设置为null