隊列的理解與實現[數據結構]

一.基礎知識

1.什麼是隊列?

滿足先進先出的一種存儲結構。

2.隊列的分類?

1.鏈式隊列(用鏈表實現的)
2.靜態隊列(用數組實現的)

3.爲什麼靜態隊列必須是循環隊列

如圖:
這裏寫圖片描述

如果不是循環隊列,那麼“隊首”以下的元素都會被浪費掉!

4.循環隊列需要幾個參數來確定?

需要兩個參數:front(隊首)、rear(隊尾)
1.隊列初始化的時候:rear=front=0
2.隊列空的時候:front==rear
3.隊列不空的時候: rear 指向隊列第1個元素、front指向隊列最後一個元素的下一個元素(目的是爲了好判斷隊列是否爲空 )

二、隊列的實現(用數組實現循環隊列)

1.初始化一個隊列

1.1定義隊列的數據結構

//定義隊列的數據結構
typedef struct Queue
{
    int * pBase;
    int front;
    int rear;
}QUEUE,*PQUEUE;

1.2初始化一個隊列

front與rear的值都爲0。

//初始化一個隊列
void initQueue(PQUEUE pQ,int length)
{
    pQ->pBase=(int *)malloc(sizeof(int)*length);
    if(pQ->pBase==NULL)
    {
        printf("隊列初始化失敗\n");
        exit(-1);
    }
    else
    {
        pQ->front=0;
        pQ->rear=0;
    }
}

2.入隊

2.1判斷隊列是否已滿

這裏寫圖片描述

我們可以讓最後一個rear不存數據
如上圖:可以作爲一個滿隊列。判斷是否已滿就很好說了:
(rear+1)%length==front時,證明已滿

//判斷隊列是否已滿
int isFull(PQUEUE pQ,int length)
{
    //這裏是循環隊列,所以是(pQ->rear+1)%length,不是(pQ->rear+1)
    if((pQ->rear+1)%length==pQ->front)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

2.2入隊

分爲3步:
1.判斷隊列是否已滿,不滿的話則允許入隊
2.在rear處入隊
3.rear++

//入隊
void enQueue(PQUEUE pQ,int length,int val)
{
    if(isFull(pQ,length))
    {
        printf("隊列已滿,不可入隊!\n");
    }
    else
    {
        pQ->pBase[pQ->rear]=val;
        pQ->rear++;
    }
}

3.遍歷隊列

3.1判斷隊列是否爲空

如圖:當front與rear相等時,證明這是一個空隊列
(爲此,rear指向最後1個元素的下1個元素,好判斷是否爲空)
這裏寫圖片描述

//判斷隊列是否爲空
int isEmpty(PQUEUE pQ)
{
    if(pQ->front==pQ->rear)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

3.2遍歷隊列

//遍歷隊列
void traverseQueue(PQUEUE pQ)
{
    if(isEmpty(pQ))
    {
        printf("空隊列\n");
    }
    else
    {
        int i=pQ->front;
        while(i!=pQ->rear)
        {
            printf("%d ",pQ->pBase[i]);
            i++;
        }
    }
}

4.出隊

//出隊
void deQueue(PQUEUE pQ,int length)
{
    if(isEmpty(pQ))
    {
        printf("隊列爲空,不可出隊\n");
    }
    else
    {
        //循環隊列,所以是(pQ->front+1)%length
        pQ->front=(pQ->front+1)%length;
    }
}

三、總體代碼

#include <stdio.h>
#include <stdlib.h>
//定義隊列的數據結構
typedef struct Queue
{
    int * pBase;
    int front;
    int rear;
}QUEUE,*PQUEUE;
//初始化一個隊列
void initQueue(PQUEUE pQ,int length)
{
    pQ->pBase=(int *)malloc(sizeof(int)*length);
    if(pQ->pBase==NULL)
    {
        printf("隊列初始化失敗\n");
        exit(-1);
    }
    else
    {
        pQ->front=0;
        pQ->rear=0;
    }
}
//判斷隊列是否已滿
int isFull(PQUEUE pQ,int length)
{
    if((pQ->rear+1)%length==pQ->front)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}
//入隊
void enQueue(PQUEUE pQ,int length,int val)
{
    if(isFull(pQ,length))
    {
        printf("隊列已滿,不可入隊!\n");
    }
    else
    {
        pQ->pBase[pQ->rear]=val;
        pQ->rear++;
    }
}
//判斷隊列是否爲空
int isEmpty(PQUEUE pQ)
{
    if(pQ->front==pQ->rear)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}
//遍歷隊列
void traverseQueue(PQUEUE pQ)
{
    if(isEmpty(pQ))
    {
        printf("空隊列\n");
    }
    else
    {
        int i=pQ->front;
        while(i!=pQ->rear)
        {
            printf("%d ",pQ->pBase[i]);
            i++;
        }
    }
}
//出隊
void deQueue(PQUEUE pQ,int length)
{
    if(isEmpty(pQ))
    {
        printf("隊列爲空,不可出隊\n");
    }
    else
    {
        pQ->front=(pQ->front+1)%length;
    }
}
int main()
{
    QUEUE q;
    initQueue(&q,6);
    enQueue(&q,6,3);
    enQueue(&q,6,2);
    enQueue(&q,6,1);
    enQueue(&q,6,4);
    enQueue(&q,6,5);
    deQueue(&q,6);
    deQueue(&q,6);
    deQueue(&q,6);
    traverseQueue(&q);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章