循环队列中显示函数的问题

Problem with display function inside circular queue

#include <stdio.h>

# define MAX 3
int queue[MAX];  // array declaration
int front=-1;
int rear=-1;
// function to insert an element in a circular queue
void enqueue(int element)
{
    if(front==-1 && rear==-1)   // condition to check queue is empty
    {
        front=0;
        rear=0;
        queue[rear]=element;
    }
    else if((rear+1)%MAX==front)  // condition to check queue is full
    {
        printf("Queue is overflow..");
    }
    else
    {
        rear=(rear+1)%MAX;       // rear is incremented
        queue[rear]=element;     // assigning a value to the queue at the rear position.
    }
}

// function to delete the element from the queue
int dequeue()
{
    if((front==-1) && (rear==-1))  // condition to check queue is empty
    {
        printf("\nQueue is underflow..");
    }
 else if(front==rear)
{
   printf("\nThe dequeued element is %d", queue[front]);
   front=-1;
   rear=-1;
}
else
{
    printf("\nThe dequeued element is %d", queue[front]);
   front=(front+1)%MAX;
}
}
// function to display the elements of a queue
void display()
{
    int i=front;
    if(front==-1 && rear==-1)
    {
        printf("\n Queue is empty..");
    }
    else
    {
        printf("\nElements in a Queue are :");
        while(i<=rear)
        {
            printf("%d,", queue[i]);
            i=(i+1)%MAX;
        }
    }
}
int main()
{
    int choice=1,x;   // variables declaration

    while(choice<4 && choice!=0)   // while loop
    {
    printf("\nPress 1: Insert an element");
    printf("\nPress 2: Delete an element");
    printf("\nPress 3: Display the element");
    printf("\nEnter your choice");
    scanf("%d", &choice);

    switch(choice)
    {

        case 1:

        printf("Enter the element which is to be inserted");
        scanf("%d", &x);
        enqueue(x);
        break;
        case 2:
        dequeue();
        break;
        case 3:
        display();

    }}
    return 0;
}

我的显示功能有问题如果后方在某些情况下可以小于前面,我如何打印所有元素例如在这段代码中,我尝试将 3 个元素 1、2、3 入队,然后将两个元素出队,我的意思是这里1,2 之后我尝试再次查询两个元素 1,2 最后当我尝试显示元素时我什么也得不到所以什么是显示队列元素的完美方式

TL;DR 版本:制作循环缓冲区的困难部分是从空条件中区分满条件,因为它们都是 front == rear,除非您采取额外的步骤,例如跟踪大小或维护 bool full; 或阻止 rear 赶上 front.

我喜欢后一种方法,因为它的代码非常简单。我喜欢写简单的代码。您不必像调试它那样苦苦思索。您不必花那么多时间来编写它。您不会被支持它的维护团队打扰。简单的代码只有在太简单而漏掉一个案例时才会成为问题。

所以我在这里简单一点。

在我认为合适的地方嵌入评论,因为当解释与所解释的内容接近时更容易理解。

#include <stdio.h>


// made MAX one bigger
// If we waste a space in the queue the only time front can be the same as rear 
// is if the queue is empty. No ambiguity. No special code for special cases or 
// extra tracking variables to tell full from empty.
// All for the low, low price of one queue element.
# define MAX 4
// in full on c++ this would be constexpr int MAX = 4;
// In general avoid macros because they are really stupid. With a macro any 
// token MAX will be replaced with 4 no matter how bad an idea it is. The 
// resulting compiler errors get really weird.
// with a constexpr, the compiler will not substitute anything and will take 
// context into account, giving much better diagnostics if you screw up

int queue[MAX]; // array declaration
                // Don't comment the obvious stuff
                // it just clutters up the code and makes you look... well..
                // Hey, look! Dummy here needs a comment to rem'ber he's 
                // defining an array! HA HA HA HA HA!
                // You've got better things to do than put up with smurf like that.
int front=0;
int rear=0;
// global variables suck. Because a global can be changed by anything at any 
// time tracking errors is a pain in the neck. Every function could have 
// unexpected side effects and needs to be examined while debugging.  

// Plus because these variables are global and shared, you can only ever have 
// ONE queue and EVERYBODY can use it.

// These variables and the queue-handling functions should be in a queue class, 
// and there should be an instance of this class defined in main.


// helper functions to keep repetition down.
// Also a well-named helper makes what's happening brutally obvious to anyone 
// reading the code
int advance(int pos)
{
    return (pos+1)%MAX;
}

bool empty()
{
    return front == rear;
}

bool full()
{
    return front == advance(rear);
    // because of the wasted space telling full from empty is dead easy 
}

// function to insert an element in a circular queue
void enqueue(int element)
{
    if(full()) // see? Much easer to read than if (front == (rear+1)%MAX)
               // now we barely need to comment.
    {
        printf("Queue is overflow.\n");
    }
    else
    {
        queue[rear]=element;     
        rear = advance(rear);
    }
}

// function to delete the element from the queue
void dequeue()
{
    if(empty())
    {
        printf("Queue is underflow.\n");
    }
    else
    {
        printf("The dequeued element is %d\n", queue[front]);
        front = advance(front);
    }
}

// function to display the elements of a queue
void display()
{
    if(empty())
    {
        printf("Queue is empty.");
    }
    else
    {
        int i = front;
        printf("Elements in a Queue are :");
        while(i!=rear)
        {
            printf("%d,", queue[i]);
            i = advance(i);
        }
    }
    printf("\n");
}

// test the logic in small chunks. Make sure the queue works perfectly before 
// slapping in a menu system. If there's a bug, you don't have to ask if it's 
// in the menu or in the queue because you're only testing one thing at a time
// when you know they both work separately, put 'em together and test again 
// just to be on the safe side.
int main()
{
    display();
    enqueue(1);
    display();
    dequeue();
    display();
    enqueue(2);
    display();
    enqueue(3);
    display();
    enqueue(4);
    display();
    enqueue(5); // fail
    display();
    enqueue(6); // fail
    display();
    dequeue();
    display();
    dequeue();
    display();
    dequeue();
    display();
    dequeue(); // fail
    display();
    dequeue(); // fail
    display();

   return 0;
}

所以...这是一个可行的解决方案。

#include <stdio.h>

# define MAX 3

class CircularQueue
{

private:
    int queue[MAX];  // array declaration
    int front;
    int rear;

public:
    CircularQueue() :
        front(-1),
        rear(-1)
    { }

    // function to insert an element in a circular queue
    void enqueue(int element)
    {
        if(front==-1 && rear==-1)   // condition to check queue is empty
        {
            front=0;
            rear=0;
            queue[rear]=element;
        }
        else if((rear+1)%MAX==front)  // condition to check queue is full
        {
            printf("Queue is overflow..\n");
        }
        else
        {
            rear=(rear+1)%MAX;       // rear is incremented
            queue[rear]=element;     // assigning a value to the queue at the rear position.
        }
    }

    // function to delete the element from the queue
    void dequeue()
    {
        if((front==-1) && (rear==-1))  // condition to check queue is empty
        {
            printf("Queue is underflow..\n");
        }
        else if(front==rear)
        {
            printf("The dequeued element is %d\n", queue[front]);
            front=-1;
            rear=-1;
        }
        else
        {
            printf("The dequeued element is %d\n", queue[front]);
            front=(front+1)%MAX;
        }
    }

    // function to display the elements of a queue
    void display()
    {
        if(front==-1 && rear==-1)
            printf("Queue is empty..\n");
        else
        {
            printf("Elements in a Queue are: ");
            int i=front;
            do
            {
                if (i != front)
                    printf(",");
                printf("%d", queue[i]);
                i=(i+1)%MAX;
            } while (i != (rear+1)%MAX);
            printf("\n");
        }
    }
};

int main()
{
    CircularQueue cq;

    unsigned int choice=1;   // variables declaration

    while(choice<4 && choice!=0)   // while loop
    {
        printf("Press 1: Insert an element\n");
        printf("Press 2: Delete an element\n");
        printf("Press 3: Display the element\n");
        printf("Press any other number to exit\n");
        printf("Enter your choice: ");
        scanf("%d", &choice);

        switch(choice)
        {

        case 1:
            printf("Enter the element which is to be inserted: ");
            int x;
            scanf("%d", &x);
            cq.enqueue(x);
            break;
        case 2:
            cq.dequeue();
            break;
        case 3:
            cq.display();
        }
    }
    return 0;
}

我对输出进行了一些更改,请参阅 \n 的位置。如果当前输出完成,最好给下一个打印语句一个新的行来写入。

最大的变化,我把所有东西都放在一个class里了。这样你就没有任何全局变量,这对 99.999% 来说是一件坏事。您的代码非常像 C,所以通常我也会使用 std::cout 并且使用 std::vector 您可以轻松地使缓冲区具有任意大小。

这是一些输出:

Press 1: Insert an element
Press 2: Delete an element
Press 3: Display the element
Press any other number to exit
Enter your choice: 1
Enter the element which is to be inserted: 2
Press 1: Insert an element
Press 2: Delete an element
Press 3: Display the element
Press any other number to exit
Enter your choice: 3
Elements in a Queue are: 2
Press 1: Insert an element
Press 2: Delete an element
Press 3: Display the element
Press any other number to exit
Enter your choice: 4