简体   繁体   English

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

[英]Implementing priority queue in C++

I am trying to implement a queue using a circular array. 我正在尝试使用循环数组实现队列。 My code is supposed to be able to remove the lowest number from the queue. 我的代码应该能够从队列中删除最小的数字。 I created test code that should output 1 2 3 4 5 as the lowest values being removed but my actual output is 3 2 1 8 7. I am not sure if my problem is that my code for finding the lowest value is incorrect or there is a problem with how i am coding the actual queue. 我创建的测试代码应该输出1 2 3 4 5作为最低值被删除但我的实际输出是3 2 1 8 7.我不确定我的问题是我的代码找到最低值是不正确还是有我如何编码实际队列的问题。 I suspect both but I'd appreciate any suggestions or tips to finding the problems in my code. 我怀疑两者,但我很感激任何建议或提示,以找到我的代码中的问题。

#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;
}

You do find the smallest value however it is not the value that you return when you extract min: 您确实找到了最小的值,但它不是您提取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

I think that what you want to do is find the smallest number then remove it from the array and return it. 我认为你想要做的是找到最小的数字,然后从数组中删除它并返回它。

This is maybe not the most clean solution but it will solve your problem: 这可能不是最干净的解决方案,但它可以解决您的问题:

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;

If i were to implement a priority queue i would ensure to allways put the smallest value at front and make sure that the array is sorted when i do insert. 如果我要实现优先级队列,我将确保总是将最小值放在前面,并确保在插入时对数组进行排序。

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;

Adding this to your insert would sort of work however first time when the following snippet is run front will be set to one. 将此添加到您的插入中会有一些工作但是第一次将前面的代码片段设置为1。 which means you will skip the first value in the queue. 这意味着您将跳过队列中的第一个值。

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

I would suggest making the above change in insert and change your extractmin to something like this: 我建议在insert中进行上述更改并将extractmin更改为以下内容:

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

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

assuming you fix this small issue: 假设您解决了这个小问题:

//return smallest value
    return array[front];

where you are returning the front of the queue not the smallest element, 你在哪里返回队列的前面而不是最小的元素,

you still have a problem in your code because it's behaving strange (for a queue): suppose your queue size is 4 and you have elements 3 1 2 4 int the queue; 您的代码中仍然存在问题,因为它的行为很奇怪(对于队列):假设您的队列大小为4并且队列中有元素3 1 2 4; in that order. 以该顺序。 When you extract, you return 1, and now if you insert a new element, 5, your queue will contain 5,1,2,4; 提取时,返回1,现在如果插入新元素5,则队列将包含5,1,2,4; So you overwrote the wrong element; 所以你覆盖了错误的元素;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM