佇列的順序儲存和鏈式儲存
阿新 • • 發佈:2019-01-07
佇列的基本概念
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;
}
}