隊列先進先出,涉及到兩個位置的操作,一個是隊首,一個是隊尾,我們分別用兩個整型變量來表示隊首和隊尾,另外需要注意的是我們實現隊列時要藉助循環數組,具體在代碼中已經很清楚了。實現過程中的技巧與用數組實現棧時大多數一樣。
首先,我們來聲明類型,結構和例程。
/**
* @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));
}
經過了這幾個程序,我們大體上已經掌握了鏈表,隊列和棧的基本實現和常用例程,當然,這只是個基礎,對於這幾個程序,一個合格的程序員應該做到爛熟於心,關於這幾個數據結構的常用應用,我會在後面慢慢來做,下一步,我們就開始學習數據結構中另一個非常重要的部分—排序。