使用C ++循环实现队列数据结构

时间:2015-08-11 13:44:15

标签: c++ data-structures

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

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

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

  3. 我的代码:

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

    谢谢!

2 个答案:

答案 0 :(得分:3)

1.显示空队列

即使在空队列中删除元素也能很好地工作。但是,空队列的显示有问题:

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

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

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

2.填充队列

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

所以你开始你的for循环,我是0,然后循环并打印出每个元素。 irear的最后一个元素是capacity-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 :(得分:1)

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