数据结构 循环队列(C++)

1、队列

队列是一种先进先出(FIFO)的线性表。只允许在队头删除元素,队尾插入元素。头删尾插。

表尾(An)是队尾,表头(A1)是队头。只能在队头队尾进行操作。常用循环顺序表。

生活中的排队问题都可以用队列 

2、队列存储结构

队列的顺序结构→一维数组base[MAXQSIZE]

除了用一组地址连续的存储单元依次存放从队头到队尾的元素外,还需增加两个整型变量front和rear分别指示队头元素和队尾元素位置。(后称头指针和尾指针,不是链表的指针,仅代表元素位置。)

typedef struct {
   QElemType *base;//初始化时动态分配存储空间
   int front;//头指针
   int rear;//尾指针
} SqQueue;

 初始化创建空队列时,令front=rear=0,队尾插入新元素时,尾指针rear自增,队头删除元素时,头指针front自增。因此,在非空队列中,头指针始终指向队头元素,而尾指针始终指向队尾元素的下一个位置。

3、基本实现

 空队列:rear==front

入队:base[rear]=x;rear++;

出队:x=base[front];front++;

当处于图(d)状态时不可插入新元素,否则会溢出。但实际上为空间未占满,为“假溢出”。为避免该情况,使用循环队列。

4、循环队列

将base[0]接在base[MAXQSIZE-1]后,使队列变成一个环状的空间。若rear+1==MAXQSIZE,则令rear=0。利用模运算(%)。

插入元素:Q.base[Q.rear]=x;
Q.rear=(Q.rear+1)% MAXQSIZE;
删除元素: x=Q.base[s.front]
Q.front=(Q.front+1)% MAXQSIZE

*对于循环队列,不能以头尾指针值来判断满队/空队

 当队列空间大小为m时,有m-1个元素就认为是队满。这样判断队空的条件不变。尾指针在循环意义上+1后等于头指针,则为队满。


判断队空

bool QueueEmpty(SqQueue q)
{
    if (q.front == q.rear)
        return 1;
    return 0;
}

5、初始化

Status InitQueue(SqQueue &q)   //构造一个空队列Q
{
   q.base = new QElemType[MAXQSIZE]; //为队列分配一个最大容量为MAXSIZE的数组空间,base指向数组空间首地址。
   if(!q.base)
      exit(OVERFLOW); //存储分配失败
   q.front = q.rear = 0; //头指针和尾指针置为零,队列为空
   return OK;
}

6、销毁队列

void DestroyQueue(SqQueue &q)
{
   /* 销毁队列Q,Q不再存在 */
   if(q.base)
      delete []q.base;
   q.base = NULL;
   q.front = q.rear = 0;
}

7、队列长度

对于循环队列,差值可能为负数,所以需要将差值加上MAXQSIZE后与MAXQSIZE求余。

// 算法3.12 求循环队列的长度
int QueueLength(SqQueue q) // 返回Q的元素个数,即队列的长度
{
    return (q.rear - q.front+ MAXQSIZE) % MAXQSIZE;
}

8、入队

①判断是否队满

②插入新元素到队尾

③队尾指针+1

Status EnQueue(SqQueue &q, QElemType e) // 插入元素e为Q的新的队尾元素
{
    if ((q.rear + 1) % MAXQSIZE == q.front)
        return ERROR;
    q.base[q.rear] = e;
    q.rear = (q.rear + 1) % MAXQSIZE;
    return OK;
}

9、出队

①判断是否队空

②保存队头元素

③队头指针+1

Status DeQueue(SqQueue &q, QElemType &e) // 删除Q的队头元素,用e返回其值
{
    if (q.front == q.rear)
        return ERROR;
    e = q.base[q.front];
    q.front = (q.front + 1) % MAXQSIZE;
    return OK;
}

10、取队头元素

// 算法3.15 取循环队列的队头元素
QElemType GetHead(SqQueue q) // 返回Q的队头元素,不修改队头指针
{
    if (q.front != q.rear) return q.base[q.front];
}

11、输出队列

void PrintQueue(SqQueue q)
{
    for (int i = q.front; i != q.rear; i = (i + 1) % MAXQSIZE)
    {
        if (i != q.front)
            cout << ' ';
        cout << q.base[i];
    }
    cout << endl;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值