1. 程式人生 > >佇列的順序儲存和鏈式儲存

佇列的順序儲存和鏈式儲存

佇列的基本概念

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;
    }
}