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

来源:互联网 发布:tplink路由器访客网络 编辑:程序博客网 时间:2024/06/06 16:31

队列的基本概念

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 oncetypedef int ELEM_TYPE;#define MAXSIZE 10typedef 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 oncetypedef 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;    }}
原创粉丝点击