您的位置:首页 > 其它

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

2017-08-10 19:01 411 查看

队列的基本概念

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;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: