请问需要加等号吗?为什么运行结果都对呢?

#include<iostream>
using namespace std;

const int MAXSIZE=100;
typedef int ElemType;
typedef struct
{
    ElemType data[MAXSIZE];
    int front;
    int rear;
}SeqQueue;

void InitQueue(SeqQueue &Q)
{
    Q.front=Q.rear=0;
}

void EnQueue(SeqQueue &Q,ElemType x)
{
    if((Q.rear+1)%MAXSIZE==Q.front)
    {
        cout<<"队列已满"<<endl;
        exit(1);
    }
    Q.rear=(Q.rear+1)%MAXSIZE;
    Q.data[Q.rear]=x;
}

ElemType DeQueue(SeqQueue &Q)
{
    if(Q.front==Q.rear)
    {
        cout<<"队列已空"<<endl;
        exit(1);
    }
    
    Q.front=(Q.front+1)%MAXSIZE;
    ElemType x=Q.data[Q.front];
    return x;
}

bool QueueEmpty(SeqQueue &Q)
{
    return Q.front==Q.rear;
}

bool QueueFull(SeqQueue &Q)
{
    return (Q.rear+1)%MAXSIZE==Q.front;
}

int QueueLength(SeqQueue &Q)
{
    return (Q.rear-Q.front+MAXSIZE)%MAXSIZE;
}

ElemType QueueMax(SeqQueue &Q)
{
    int i;
    int f=(Q.front+1)%MAXSIZE;
    ElemType max=Q.data[f];
    
    for(i=1;i<QueueLength(Q);i++)
        if(max<Q.data[f+i])
           max=Q.data[f+i];
           
    
    return max;
}

int main()
{
    SeqQueue Q;
    
    int time=0;
    ElemType e;
    int x,flag,index;

    InitQueue(Q);
    cout<<"请输入打印队列,以-1结束:";
    cin>>e;
    while(e!=-1)
    {
        EnQueue(Q,e);
        cin>>e;
    }
    
    cout<<"请输入需打印任务在队列中的位置:";
    cin>>x;
    if(x>QueueLength(Q))
    {
        cout<<"输入的位置有误!\n";
        return 0; 
    }
    flag=x;         //设置需打印任务在队列中的位置
    while(!QueueEmpty(Q)) 
    {
        e=DeQueue(Q);
        flag--;
        if(e<QueueMax(Q))
        { 
        
            EnQueue(Q,e);
            if(flag==0)
               flag=QueueLength(Q);
        }
        else
        {
            time++;
            if(flag==0)
               break;
        }
    }
    cout<<"完成打印任务所需时间为:"
        <<time<<"min.\n";
    
    return 0;
}

上面QueueMax函数中有一行for(i=1;i<QueueLength(Q);i++),书上写的是i<=QueueLength(Q)。请问需要加等号吗?
为什么运行结果都对呢?

阅读 1.7k
2 个回答

等号不能加。
加了之后发现运行结果没差,很可能是 Q.front 指向的元素为零。这纯粹是巧合。
@刘云宾 所言,QueueMax 函数中,必须对数组索引做校验。

请参考

ElemType QueueAt(SeqQueue &Q, int seq)
{
    if(seq < 0 || seq >= QueueLength(Q))
    {
        cout<<"索引超标"<<endl;
        exit(1);
    }

    int index = (Q.front + 1 + seq) % MAXSIZE;
    return Q.data[index];
}

ElemType QueueMax(SeqQueue &Q)
{
    if(QueueEmpty(Q))
    {
        cout<<"空队列"<<endl;
        exit(1);
    }

    ElemType val = QueueAt(Q, 0);
    for (int i = 1; i < QueueLength(Q); i++ ) {
        ElemType curr = QueueAt(Q, i);
        if (curr > val)
            val = curr;
    }
    return val;
}

ElemType QueuePrint(SeqQueue &Q)
{
    printf("== queue ==\n");
    int len = QueueLength(Q);
    for (int i = 0; i < len; i++) {
        printf("#%d: %d\n", i, QueueAt(Q, i));
    }
    printf("\n");
}

更新说明:

以下代码仅按照思路 rear 指向队列最后一个元素的下一位置,front 指向队列的首位置说明,和题主的思路不同。

=====================================================================

这个队列写的有问题,按照代码,队列有以下设计:

  1. 如果队列为空,rear == front
  2. 如果队列不为空,rear 指向队列最后一个元素的下一位置,front 指向队列的首位置

照这个思路,函数 void EnQueue(SeqQueue &Q,ElemType x) 是错误的,因为这个函数如果依次插入 1, 2,结果将是:空,1,空, 2。正确的写法是,先插入元素,再增加 rear 的值,见:

void EnQueue(SeqQueue &Q,ElemType x)
{
    if((Q.rear+1)%MAXSIZE==Q.front)
    {
        cout<<"队列已满"<<endl;
        exit(1);
    }
    Q.data[Q.rear]=x;
    Q.rear=(Q.rear+1)%MAXSIZE;
}

同理,函数 ElemType DeQueue(SeqQueue &Q) 也是错误的,因为对于队列,1, 2, 3,这个函数如果删除元素将返回 2 而不是 1。正确的写法是,先获取返回的元素,再增加 front 的值,见:

ElemType DeQueue(SeqQueue &Q)
{
    if(Q.front==Q.rear)
    {
        cout<<"队列已空"<<endl;
        exit(1);
    }
    ElemType x=Q.data[Q.front];
    Q.front=(Q.front+1)%MAXSIZE;
    return x;
}

至于函数,ElemType QueueMax(SeqQueue &Q) 也是错误的,需要首先判断队列是否为空,其次必须对索引必须使用 MAXSIZE 求余,见:

ElemType QueueMax(SeqQueue &Q)
{
    if(Q.front==Q.rear)
    {
        cout<<"队列已空"<<endl;
        exit(1);
    }
    int i;
    int f=Q.front;
    ElemType max=Q.data[f];
    
    for(i=1;i<QueueLength(Q);i++)
        if(max<Q.data[(f+i)%MAXSIZE])
           max=Q.data[(f+i)%MAXSIZE];
    return max;
}

顺便说一句,如果你书上的代码就是这,建议你换一本书。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题