基本數據結構 -- 隊列(數組實現)

  隊列是一種先進先出(FIFO)的線性表。對隊列的基本操做有兩種: 入隊(Enqueue),在表的末端(隊尾 tail)插入一個元素;出隊(Dequeue),刪除或返回在表的開頭(隊頭 head)的元素。本文介紹如何使用數組在 C 語言中實現一個隊列,平臺爲VS2010。算法

  先建立一個隊列結構體,這個結構體應該包括這幾個元素:隊頭在數組中的位置(Front)、隊尾在數組中的位置(Rear)、隊列的大小(Size)、用於存儲隊列的數組(Array)以及數組的容量(Capacity):數組

typedef int ElementType;

struct QueueRecord {
    int Capacity;          // 數組容量
    int Front;             // 隊頭的位置
    int Rear;              // 隊尾的位置
    int Size;             // 隊列大小
    ElementType *Array;    // 用於存放隊列的數組
};

typedef struct QueueRecord Queue;
typedef struct QueueRecord *PtrToQueue;

 

1、建立隊列數據結構

  使用前面的結構體來建立一個隊列:ide

PtrToQueue CreateQueue(int capacity)
{
    PtrToQueue queue = (PtrToQueue )malloc(sizeof(Queue));
    if (queue == NULL) {
        perror("malloc failed!\n");
        exit(EXIT_FAILURE);
    }

    queue->Capacity = capacity;
    queue->Array = (ElementType *)malloc(sizeof(ElementType) * capacity);
    MakeEmpty(queue);

    return queue;
}


void MakeEmpty(PtrToQueue Q)
{
    Q->Size = 0;  // 隊列長度設爲1
    Q->Front = 1;  // 隊頭位置爲 1
    Q->Rear = 0;    // 隊尾位置爲 0
}

 

2、入隊操做spa

   向指定隊列的尾部插入一個元素,即爲入隊操做。在每次插入以前都要判斷隊列是否還有空間供新元素插入。code

void Enqueue(PtrToQueue Q,ElementType element)
{
    if (IsFull(Q)) {
        perror("隊列已滿,入隊失敗\n");
        exit(EXIT_FAILURE);
    }
    else {
        Q->Size++;    // 隊列大小加 1
        if (++Q->Rear == Q->Capacity) {
            Q->Rear = 0;
        }
        Q->Array[Q->Rear] = element;
    }
}

bool IsFull(PtrToQueue Q)
{
    return Q->Size == Q->Capacity;
}

  在入隊操做中,設置了一個循環數組,在隊尾位置要超出數組邊界時,將隊尾放到數組開始處,以便最大利用數組空間。 blog

  

3、出隊操做隊列

   將隊列的隊頭元素從隊列中刪除,對於數組隊列,只須要將隊頭位置加 1 便可。ci

void Dequeue(PtrToQueue Q)
{
    if (IsEmpty(Q)) {
        perror("隊列爲空,沒法執行出隊操做\n");
        exit(EXIT_FAILURE);
    }
    else {
        Q->Size--;    // 隊列大小減 1
        if (++Q->Front == Q->Capacity) {
            Q->Front = 0;
        }        
    }

}

bool IsEmpty(PtrToQueue Q)
{
    return Q->Size == 0;
}

  一樣的,爲了最大利用數組空間,出隊操做也使用了循環數組。 element

 

4、遍歷隊列

  從隊頭元素開始遍歷整個隊列:

void TraverseQueue(PtrToQueue Q)
{
    if (Q->Size == 0) {
        printf("隊列爲空\n");
    }

    for (int i = 0; i < Q->Size; i++) {
        if (Q->Front + i < Q->Capacity) {
            printf("%d ", Q->Array[Q->Front + i]);
        }
        else {
            printf("%d ", Q->Array[Q->Front + i - Q->Capacity]);
        }
        
    }
}

 

5、完整代碼

#include <stdio.h>
#include <stdlib.h>

typedef int ElementType;

struct QueueRecord {
    int Capacity;        // 數組容量
    int Front;            // 隊頭的位置
    int Rear;            // 隊尾的位置
    int Size;            // 隊列大小
    ElementType *Array;    // 用於存放隊列的數組
};

typedef struct QueueRecord Queue;
typedef struct QueueRecord *PtrToQueue;

PtrToQueue CreateQueue(int capacity);
void MakeEmpty(PtrToQueue Q);
void Enqueue(PtrToQueue Q, ElementType element);
void Dequeue(PtrToQueue Q);
bool IsFull(PtrToQueue Q);
bool IsEmpty(PtrToQueue Q);
void TraverseQueue(PtrToQueue Q);
ElementType Peek(PtrToQueue Q);


int main()
{
    PtrToQueue newQueue = CreateQueue(10);    // 建立一個空隊列
    for (int i = 0; i < 10; i++) {
        Enqueue(newQueue,i);            // 向隊列中添加元素
    }
    
    TraverseQueue(newQueue);            // 遍歷隊列

    Dequeue(newQueue);                // 出隊
    Dequeue(newQueue);                // 出隊
    TraverseQueue(newQueue);

    Enqueue(newQueue, 50);             // 入隊
    TraverseQueue(newQueue);

    return 0;
}

// 建立一個隊列
PtrToQueue CreateQueue(int capacity)
{
    PtrToQueue queue = (PtrToQueue )malloc(sizeof(Queue));
    if (queue == NULL) {
        perror("malloc failed!\n");
        exit(EXIT_FAILURE);
    }

    queue->Capacity = capacity;
    queue->Array = (ElementType *)malloc(sizeof(ElementType) * capacity);
    MakeEmpty(queue);

    return queue;
}


void MakeEmpty(PtrToQueue Q)
{
    Q->Size = 0;
    Q->Front = 1;
    Q->Rear = 0;
}

// 入隊
void Enqueue(PtrToQueue Q,ElementType element)
{
    if (IsFull(Q)) {
        perror("隊列已滿,入隊失敗\n");
        exit(EXIT_FAILURE);
    }
    else {
        Q->Size++;
        if (++Q->Rear == Q->Capacity) {
            Q->Rear = 0;
        }
        Q->Array[Q->Rear] = element;
        
    }
}

// 出隊
void Dequeue(PtrToQueue Q)
{
    if (IsEmpty(Q)) {
        perror("隊列爲空,沒法執行出隊操做\n");
        exit(EXIT_FAILURE);
    }
    else {
        Q->Size--;
        if (++Q->Front == Q->Capacity) {
            Q->Front = 0;
        }        
    }

}

// 判斷隊列是否爲滿
bool IsFull(PtrToQueue Q)
{
    return Q->Size == Q->Capacity;
}

// 判斷隊列是否爲空
bool IsEmpty(PtrToQueue Q)
{
    return Q->Size == 0;
}

// 遍歷隊列
void TraverseQueue(PtrToQueue Q)
{
    if (Q->Size == 0) {
        printf("隊列爲空\n");
    }

    for (int i = 0; i < Q->Size; i++) {
        if (Q->Front + i < Q->Capacity) {
            printf("%d ", Q->Array[Q->Front + i]);
        }
        else {
            printf("%d ", Q->Array[Q->Front + i - Q->Capacity]);
        }    
    }

    printf("\n");
}

// 獲取隊頭元素
ElementType Peek(PtrToQueue Q)
{
    return Q->Array[Q->Front];
}
View Code

   這段代碼建立了一個隊列,將整數 0~9分別入隊,而後執行兩次出隊操做,再將整數 50 入隊,程序執行結果以下:

 

參考資料:

《數據結構與算法分析 -- C語言描述》

相關文章
相關標籤/搜索