队列的顺序存储和链式存储

队列的基本概念

1.定义:队列是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。
2.队列是一种先进先出的线性表,简称FIFO。允许插入的一端称为队尾,允许删除的一端称为队头。front指针指向对头元素,rear指针指向队尾的下一个位置。当front==rear时,为空队列。

队列的顺序存储(循环队列)

如图所示为队列的顺序存储
这里写图片描述

假设这个队列的总个数不超过5个,但目前如接着入队的话,因数组末尾元素已经占用,再向后加,就会出现数组越界的错误,可实际上,队列在下标0和1的地方还是空闲的。把这种现象称为“假溢出”。
这也是队列的顺序存储不足的地方。所以解决假溢出的办法就是后面满了,就再从头开始,也就是头尾相接的循环。
我们把队列的这种头尾相接的顺序存储结构称为循环队列。
判断队列满的条件:
*办法一是设置一个标志变量flag,当front==rear,且flag=0是为队列空,当front=rear,且flag=1时为队列满。
*办法二是当队列空时,条件就是front=rear,当队列满时,保留一个元素空间,数组中还有一个空闲单元。如图所示:
这里写图片描述

这里主要讨论第二种方法:由于rear可能比front大,也可能比front小,所以尽管它们只相差一个位置时就是满的情况,但也可能是相差整整一圈。所以若队列的最大尺寸为QueueSize,那么队列满的条件是:
(rear+1)%QueueSize == front
而队列的长度计算公式为:
(rear-front+QueueSize)%QueueSize
循环队列的代码实现:

"sqqueue.h"

#pragma once

typedef int ELEM_TYPE;
#define MAXSIZE 10
typedef struct
{
    ELEM_TYPE data[MAXSIZE];
    int front;      //头指针
    int rear;       //尾指针,若队列不为空,指向队列尾元素的下一个位置
}SqQueue;

void InitQueue(SqQueue *q);
void EnQueue(SqQueue *q,ELEM_TYPE e);
void DeQueue(SqQueue *q,ELEM_TYPE *e);
bool QueueEmpty(SqQueue q);
int QueueLength(SqQueue q);
void ClearQueue(SqQueue *q);
void DestroyQueue(SqQueue *q);
void QueueHead(SqQueue q,ELEM_TYPE *e);
void ShowQueue(SqQueue q);

"sqqueue.cpp"

#include "sqqueue.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

void InitQueue(SqQueue *q)
{
    q->front = NULL;
    q->rear = NULL;
    int i;
    for (i=0;i<MAXSIZE;++i)
    {
        q->data[i] = 0;
    }
}

void EnQueue(SqQueue *q,ELEM_TYPE e)
{
    if ((q->rear+1)%MAXSIZE == q->front)
    {
        printf("队列满\n");
        return;
    }
    q->data[q->rear] = e;
    q->rear = (q->rear+1)%MAXSIZE;//rear指针向后移动一个位置,若到最后则返回数组头部
}

void DeQueue(SqQueue *q,ELEM_TYPE *e)
{
    if(q->front == q->rear)
    {
        printf("队列为空\n");
        return;
    }
    *e = q->data[q->front];
    q->front = (q->front+1)%MAXSIZE;//头指针向后移一个位置,若到最后则返回到数组头部
}

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

int QueueLength(SqQueue q)
{
    return (q.rear-q.front+MAXSIZE)%MAXSIZE;
}

void ClearQueue(SqQueue *q)
{
    assert(q != NULL);
    while (q->front != q->rear)
    {
        q->front = (q->front+1)%MAXSIZE;
    }
}

void DestroyQueue(SqQueue *q)
{
    q->front = NULL;
    q->rear = NULL;
}

void QueueHead(SqQueue q,ELEM_TYPE *e)
{
    if (q.front == q.rear)
    {
        printf("队列为空z\n");
        return;
    }
    *e = q.data[q.front];
}

void ShowQueue(SqQueue q)
{

    while (q.front != q.rear)
    {
        printf("data:%d\n",q.data[q.front]);
        q.front = (q.front+1)%MAXSIZE;
    }
}

队列的链式存储

代码实现:

"linkqueue.h"

#pragma once

typedef int ELEM_TYPE;
typedef struct QNode 
{
    ELEM_TYPE data;
    struct QNode *next;
}QNode,*QueuePtr;

typedef struct  
{
    QueuePtr front;//队头指针
    QueuePtr rear;//队尾指针
}LinkQueue;

void InitQueue(LinkQueue *q);
void DestroyQueue(LinkQueue *q);
void ClearQueue(LinkQueue *q);
bool QueueEmpty(LinkQueue q);
int QueueLength(LinkQueue q);
void GetHead(LinkQueue q,ELEM_TYPE *e);
void EnQueue(LinkQueue *q,ELEM_TYPE e);
void DeQueue(LinkQueue *q,ELEM_TYPE *e);
void showQueue(LinkQueue q);

"linkqueue.cpp"

#include "linkqueue.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

void InitQueue(LinkQueue *q)
{
    q->front = q->rear = (QueuePtr)malloc(sizeof(QNode));
    if (!q->front)
    {
        exit(EXIT_FAILURE);
    }
    q->front->next = NULL;
}

void DestroyQueue(LinkQueue *q)
{
    while (q->front)
    {
        q->rear = q->front->next;
        free(q->front);
        q->front = q->rear;
    }
}

void ClearQueue(LinkQueue *q)
{
    QueuePtr p = q->front->next;
    while (p)
    {
        q->front->next = p->next;
        if (q->rear == p)
        {
            q->rear = q->front;
        }
        free(p);
        p = q->front->next;
    }
}

bool QueueEmpty(LinkQueue q)
{
    if (q.front == q.rear)
    {
        return true;
    }
    else
    {
        return false;
    }
}

int QueueLength(LinkQueue q)
{
    int i = 0;
    QueuePtr p = q.front->next;
    while(p)
    {
        i++;
        p = p->next;
    }
    return i;
}

void GetHead(LinkQueue q,ELEM_TYPE *e)
{
    QueuePtr p = q.front->next;
    if (p)
    {
        *e = p->data;
    }
}

void EnQueue(LinkQueue *q,ELEM_TYPE e)
{
    QueuePtr p = (QueuePtr)malloc(sizeof(QNode));
    if (!p)
    {
        exit(EXIT_FAILURE);
    }
    p->data = e;
    p->next = NULL;
    q->rear->next = p;
    q->rear = p;
}

void DeQueue(LinkQueue *q,ELEM_TYPE *e)
{
    if (q->front == q->rear)
    {
        printf("队列为空\n");
        return;
    }
    QueuePtr p = q->front->next;
    *e = p->data;
    q->front->next = p->next;
    if (q->rear == p)
    {
        q->rear = q->front;
    }
    free(p);
}

void showQueue(LinkQueue q)
{
    assert(q.front != NULL);
    QueuePtr p = q.front->next;
    while (p)
    {
        printf("data:%d\n",p->data);
        p = p->next;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值