【问题标题】:Circular implementation of queue data structure using C++使用C++循环实现队列数据结构
【发布时间】:2015-11-03 18:44:48
【问题描述】:

我编写了以下 C++ 代码来实现队列数据结构。但是,我有两个问题:

  1. 每当我删除前面的元素时,它都可以正常工作。但是,当我按 2 删除前面的元素时,即使队列为空,我也会收到一条消息说 “队列为空”,下一行是 5。如何防止 5 出现?为什么会出现?

  2. 当我完全填满队列并想要显示内容时,队列正在无限打印而不会停止。我认为显示函数中的 for 循环有问题。当队列未满时,显示功能正常工作。我该如何解决这个问题?

我的代码:

#include<iostream>
using namespace std;
int data;
class queue {

    private:
        int front,rear,capacity,a[100];

    public:
        queue(int n)
        {
            rear=front=-1;
            capacity=n;
        }

        void enqueue(int n)
        {
            if(front==-1)
            {
                front++;
                rear=front;
                a[front]=n;     
                return; 
            }
            if(rear%capacity==(front-1)%capacity)
            {
                cout<<"Queue is full\n";
                return;
            }
            rear=(rear+1)%capacity;
            a[rear]=n;

        }

        int dequeue()
        {
            if(front==rear&&front==-1)
            {
                cout<<"Queue is empty";
                return 0;
            }   
            if(front==rear&&front!=-1)
            {
                data=a[front];
                front=rear=-1;
                return data;
            }

            data=a[front];
            front=(front+1)%capacity;
            return data;
        }

        void display()
        {
            int i;
            for(i=front;i!=rear+1;i=(i+1)%capacity)
            cout<<a[i]<<endl;
        }

};

main()
{
    int x,y,c;
    cout<<"Enter capacity\n";
    cin>>c;
    queue q(c);

    while(1)
    {
        cout<<"Select option 1.insert 2.delete 3.display 4.exit\n";
        cin>>x;
        switch(x)
        {
            case 1: cout<<"Enter the element\n";
                    cin>>y;
                    q.enqueue(y);
                    break;
            case 2: q.dequeue();
                    break;
            case 3: q.display();
                    break;
            case 4: exit(0);                    
        }
    }
    return 0;
}

谢谢!!

【问题讨论】:

  • 问题1说“当我按3删除前面的元素时”但是2是删除命令,3是显示。这是描述中的错误,还是意味着如果您删除直到队列为空,然后显示您看到“5”是剩余数据?这表明显示循环存在另一个问题。
  • 是的,对不起。修好了!
  • 区分一个满队和一个空队的困难提醒我们天才和精神错乱之间的细微差别。

标签: c++ data-structures


【解决方案1】:

1.空队列的显示

即使在空队列中删除元素也很有效。但是空队列的显示有问题:

当队列为空时,frontrear 都是 -1。

for 循环以 i=front 开头,所以 i 为 -1

条件是i != rear + 1;,第一次为真(如-1 != 0),所以循环执行一次打印a[-1],这是未定义的行为。因此是垃圾输出。

2.满队

当队列已满时,front 为 0,rearcapactity-1

所以你以 i 为 0 开始你的 for 循环,然后你循环并打印出每个元素。最后一个元素是irearcapacity-1

当进一步迭代时,i = (i + 1) % capacity 使用 i 的当前值,这相当于 i= (capacity-1 + 1)% capacity 将是 0,在这里你再次开始循环!

随着您的增量,您将永远不会达到循环结束条件。

如何解决?

这是一个工作版本

void display()
{
    int i;
    if (front == -1)  // This is a special case
        cout << "No elements" <<endl;
    else              // now the general case: do the module in the loop body (i.e. uppon increment and success
        for (i = front; i != rear + 1; i++) 
            cout << a[i% capacity] << endl;
}

【讨论】:

  • 不错。问题已部分解决。但是假设我这样做 - 将元素 1、2、3、4、5 添加到队列中,然后删除 1 和 2。在此之后,如果我再次插入 5 和 6 并显示,队列将再次无限打印。我该如何解决这个问题?
  • 我解决了上述评论中的问题。这里: for (i = front; i != back; i=(i+1)%capacity) cout
【解决方案2】:

在 C++ 中循环队列(在本例中为整数)的更简单实现是:

CircularQueue.h:

class CircularQueue
{
public:
    CircularQueue(int n);
    ~CircularQueue();
    bool Empty();
    bool Full();
    void push(int i);
    bool front(int& i);
    void pop();
private:
    int N;
    int Capacity;
    int* buffer;
    int head;
    int tail;
};

CircularQueue.cpp:

#include "CircularQueue.h"

CircularQueue::CircularQueue(int n) : N(n) {
    Capacity = N + 1;
    buffer = new int[Capacity];
    head = 0;
    tail = 0;
}

CircularQueue::~CircularQueue()
{
    delete[] buffer;
}

bool CircularQueue::Empty()
{
    return head == tail;
}

bool CircularQueue::Full()
{
    return (head + 1) % Capacity == tail;
}

void CircularQueue::push(int i)
{
    if (!Full()) {
        buffer[head] = i;
        head = (head + 1) % Capacity;
    }
}

bool CircularQueue::front(int& i)
{
    if (!Empty()) {
        i = buffer[tail];
        return true;
    }
    else
        return false;
}

void CircularQueue::pop()
{
    if (!Empty())
        tail = (tail + 1) % Capacity;
}

参考:http://www.drdobbs.com/thread-safe-circular-queue/184401814

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-30
    • 1970-01-01
    • 2014-01-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多