在C ++中实现优先级队列

时间:2014-02-10 08:23:31

标签: c++ priority-queue dynamic-arrays

我正在尝试使用循环数组实现队列。我的代码应该能够从队列中删除最小的数字。我创建的测试代码应该输出1 2 3 4 5作为最低值被删除但我的实际输出是3 2 1 8 7.我不确定我的问题是我的代码找到最低值是不正确还是有我如何编码实际队列的问题。我怀疑两者,但我很感激在我的代码中找到问题的任何建议或提示。

#include <iostream>
using namespace std;

class priorityQueue
{
private:
    int front;
    int rear;
    int size;
    int *array;

public:
    priorityQueue();
    ~priorityQueue();
    void insert(int x);
    //remove and return the smallest item currently in the priority queue
    int extractMin();
    bool empty();
};

priorityQueue::priorityQueue()
{
    front = rear = -1;
    size = 10;
    array = new int[size];
}

priorityQueue::~priorityQueue()
{
    delete[] array;
}

void priorityQueue::insert(int x)
{
    //if queue is full
    if ( (rear + 1)% size == front ){
        return;
    }

    //else if queue is empty
    else if ( empty() ){
        rear = front = 0;
    }

    else
    {
        rear = (rear + 1) % size;
    }

    array[rear] = x;
}

//extract and return smallest value in queue
int priorityQueue::extractMin()
{
    int minValue = array[front];

    if ( empty() ){
        return -1;
    }

    else if (front == rear){
        front = rear = -1;
        }

    else
    {
        front = (front + 1) % size;
    }

    //find smallest value
    for (int i = front; i <= rear; i++){
        if (array[i] < minValue)
            minValue = array[i];
    }

    //return smallest value
    return array[front];
}

bool priorityQueue::empty()
{
    if ( (front == -1) && (rear == -1) )
        return true;
    else
        return false;
}

int main()
{
    priorityQueue myqueue;

    myqueue.insert(4);
    myqueue.insert(3);
    myqueue.insert(2);
    myqueue.insert(1);

    cout << myqueue.extractMin() << endl;
    cout << myqueue.extractMin() << endl;

    myqueue.insert(8);
    myqueue.insert(7);
    myqueue.insert(6);
    myqueue.insert(5);

    cout << myqueue.extractMin() << endl;
    cout << myqueue.extractMin() << endl;
    cout << myqueue.extractMin() << endl;

    system("pause");
    return 0;
}

2 个答案:

答案 0 :(得分:1)

您确实找到了最小的值,但它不是您提取min时返回的值:

//find smallest value
for (int i = front; i <= rear; i++){
    if (array[i] < minValue)
        minValue = array[i];
}

//return smallest value
return array[front]; //Not equal to the smallest value

我认为您要做的是找到最小的数字,然后将其从数组中删除并返回。

这可能不是最干净的解决方案,但它可以解决您的问题:

int minIndex = front;

//find smallest value
for (int i = front; i <= rear; i++){
    if (array[i] < minValue)
    {
        minIndex = i;
        minValue = array[i];
    }
}

array[minIndex] = array[front];

//return smallest value
return minValue;

如果我要实现优先级队列,我将确保总是将最小值放在前面,并确保在插入时对数组进行排序。

int index = rear;

for(int i = front ; i <= rear ; i++)
{
    if(x < array[i])
    {
        for(int j = rear ; j >= i ; j--)
        {
            array[j] = array[j-1];
        }
        index = i;
        break;
    }
}

array[index] = x;

将此添加到您的插入中会有一些工作但是第一次将前面的代码片段设置为1。这意味着你将跳过队列中的第一个值。

else
{
    front = (front+1) % size;
}

我建议在insert中进行上述更改并将extractmin更改为以下内容:

//extract and return smallest value in queue
int priorityQueue::extractMin()
{
    //Handle circulation.

    //return smallest value
    return array[front++];
}

答案 1 :(得分:1)

假设你解决了这个小问题:

//return smallest value
    return array[front];

你返回队列的前面而不是最小的元素,

你的代码中仍然存在问题,因为它的行为很奇怪(对于一个队列):假设你的队列大小为4,你在队列中有3 1 2 4个元素;以该顺序。提取时,返回1,现在如果插入新元素5,则队列将包含5,1,2,4;所以你覆盖了错误的元素;