數據結構與算法分析-用C語言實現隊列(數組方式)

隊列先進先出,涉及到兩個位置的操作,一個是隊首,一個是隊尾,我們分別用兩個整型變量來表示隊首和隊尾,另外需要注意的是我們實現隊列時要藉助循環數組,具體在代碼中已經很清楚了。實現過程中的技巧與用數組實現棧時大多數一樣。

首先,我們來聲明類型,結構和例程。

/**
* @file    Queue.h
* @brief   用鏈表實現隊列-聲明ADT部分
* @details
* @author  [email protected]
* @date    2014-5-20
*/
#include <stdio.h>
#ifndef _Queue_h

//實現隊列所需的結構和類型
typedef int ElementType;
struct QueueRecord;
typedef struct QueueRecord *Queue;

int IsEmpty(Queue Q);   //判空
int IsFull(Queue Q);    //判滿
Queue CreateQueue(int MaxElements); //創建隊列
void DisposeQueue(Queue Q); //消除隊列
void MakeEmpty(Queue Q);    //置空隊列
void Enqueue(ElementType X, Queue Q);   //入隊
ElementType Front(Queue Q); //返回隊首
void Dequeue(Queue Q);  //出隊
ElementType FrontAndDequeue(Queue Q);   //出隊並返回隊首
void FatalError(char *str); //錯誤信息
static int Succ(int Value, Queue Q);    //隊首或隊尾的前移
#endif // _Queue_h

然後實現他們:

/**
* @file    Queue.c
* @brief   用鏈表實現隊列-實現部分
* @details
* @author  [email protected]
* @date    2014-5-20
*/
#include <stdlib.h>
#include <Queue.h>
#define MinQueueSize (5)    //最小隊列大小
struct QueueRecord
{
    int Front;  //隊首
    int Rear;   //隊尾
    int Size;   //大小
    int Capacity;   //容量
    ElementType *Array; //隊列數組
};

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

//構造空隊列
void MakeEmpty(Queue Q)
{
    Q->Size = 0;
    Q->Front = 1;   //初始化隊列中隊首比隊尾大1
    Q->Rear = 0;
}

//錯誤信息
void FatalError(char *str)
{
    printf("%s", str);
}

//隊頭或隊尾的移動
static int Succ(int Value, Queue Q)
{
    if (++Value == Q->Capacity) //這裏用來實現一個循環隊列
        Value = 0;
    return Value;
}

//入隊
void Enqueue(ElementType X, Queue Q)
{
    if (Q->Size == Q->Capacity)
        FatalError("FUll Queue.");
    else
    {
        ++Q->Size;                      //大小加1
        Q->Rear = Succ(Q->Rear, Q);     //隊尾前移
        Q->Array[Q->Rear] = X;          //隊尾加入元素
    }

}

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

//創建隊列
Queue CreateQueue(int MaxElements)
{
    Queue Q;

    if (MaxElements < MinQueueSize)
        FatalError("Queue Size is too small.");

    Q = malloc(sizeof(struct QueueRecord));
    if (Q == NULL)
        FatalError("Out of space");

    Q->Array = malloc(sizeof(ElementType)*MaxElements);
    if (Q->Array == NULL)
        FatalError("Out of space.");
    Q->Capacity = MaxElements;
    MakeEmpty(Q);
    return Q;
}

//消除隊列
void DisposeQueue(Queue Q)
{
    if (Q != NULL)
    {
        free(Q->Array);
        free(Q);
    }
}

//返回隊首元素
ElementType Front(Queue Q)
{
    if(IsEmpty(Q))
        FatalError("Empty Queue");
    else
        return Q->Array[Q->Front];
    return 0;
}

//出隊
void Dequeue(Queue Q)
{
    if (IsEmpty(Q))
        FatalError("Empty Queue.");
    else
    {
        Q->Front = Succ(Q->Front, Q);
        Q->Size--;
    }
}

//出隊並返回隊首
ElementType FrontAndDequeue(Queue Q)
{
    ElementType TmpCell;

    if (IsEmpty(Q))
        FatalError("Empty Queue");
    else
    {
       Q->Size--;
       TmpCell = Q->Array[Q->Front];
       Q->Front = Succ(Q->Front,Q);
       return TmpCell;
    }
    return 0;
}

最後在主程序中測試。

/**
* @file    main.c
* @brief   用鏈表實現隊列-測試部分
* @details
* @author  [email protected]
* @date    2014-5-20
*/
#include <stdio.h>
#include <stdlib.h>
#include <Queue.h>

int main()
{
    //入隊3個並依次出隊
    Queue Q = CreateQueue(100);
    Enqueue(1,Q);
    Enqueue(2,Q);
    Enqueue(3,Q);
    while (!IsEmpty(Q))
        printf("%d\t", FrontAndDequeue(Q));
}

經過了這幾個程序,我們大體上已經掌握了鏈表,隊列和棧的基本實現和常用例程,當然,這只是個基礎,對於這幾個程序,一個合格的程序員應該做到爛熟於心,關於這幾個數據結構的常用應用,我會在後面慢慢來做,下一步,我們就開始學習數據結構中另一個非常重要的部分—排序。


發佈了86 篇原創文章 · 獲贊 35 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章