//隊列的C語言描述,選自《資料結構(c語言描述)》,徐孝凱、賀桂英,清華大學出版社。
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
//隊列的順序儲存結構同樣可以被定義在一個記錄類型中,假定該記錄類型用QueueSq表示,則定義為:
/*
struct QueueSq {
ElemType queue[MaxSize];
int front, rear, len;
};
*/
//若要對儲存隊列的數組空間採用動態分配,則QueueSq結構類型可定義為:
struct QueueSq {
ElemType *queue; /*指向儲存隊列的數組空間*/
int front, rear, len; /*隊首指標、隊尾指標、隊列長度變數*/
int MaxSize; /*queue數組長度*/
};
void againMalloc(struct QueueSq* Q)
{
/*空間擴充為原來的2倍,並由p所指向,原內容被自動
拷貝到p所指向的儲存空間中*/
ElemType *p;
p=realloc(Q->queue, 2*Q->MaxSize*sizeof(ElemType));
if(!p) { /*分配失敗退出運行*/
printf("儲存空間用完!\n");
exit(1);
}
/*使queue指向新的隊列空間*/
Q->queue=p;
/*把原隊列的尾部內容向後移動MaxSize個位置*/
if(Q->rear!=Q->MaxSize-1) {
int i;
for(i=0; i<=Q->rear; i++)
Q->queue[i+Q->MaxSize]=Q->queue[i];
Q->rear+=Q->MaxSize; /*隊尾指標後移MaxSize個位置*/
}
/*把隊列空間大小修改為新的長度*/
Q->MaxSize=2*Q->MaxSize;
}
//1. 初始化隊列
//第一種情況是隱含分配用於儲存隊列的固定大小的動態儲存裝置空間,假定動態儲存裝置空間的大小為10。
/*
void InitQueue(struct QueueSq* Q)
{
//置隊列空間初始最大長度為10
Q->MaxSize=10;
//動態儲存裝置空間分配
Q->queue=malloc(10*sizeof(ElemType));
//置隊列為空白
Q->front=Q->rear=0;
}
*/
//第二種情況是分配由參數指定大小的動態儲存裝置空間。實用中使用任一種初始化演算法均可。
void InitQueue(struct QueueSq* Q, int ms)
{
/*檢查ms是否有效,若無效則退出運行*/
if(ms<=0) {printf("ms值非法!\n"); exit(1);}
/*置隊列空間大小為ms*/
Q->MaxSize=ms;
/*動態儲存裝置空間分配,若分配失敗則退出運行*/
Q->queue=malloc(ms*sizeof(ElemType));
if(!Q->queue) {
printf("記憶體空間用完!\n");
exit(1);
}
/*初始置隊列為空白*/
Q->front=Q->rear=0;
}
//2. 向隊列插入元素
void EnQueue(struct QueueSq* Q, ElemType x)
{
/*當隊列滿時進行動態重分配*/
if((Q->rear+1)%Q->MaxSize==Q->front) againMalloc(Q);
/*求出隊尾的下一個位置*/
Q->rear=(Q->rear+1)%Q->MaxSize;
/*把item的值賦給新的隊尾位置*/
Q->queue[Q->rear]=x;
}//againMalloc()演算法的具體定義如上:
//3. 從隊列中刪除元素並返回
ElemType OutQueue(struct QueueSq* Q)
{
/*若隊列為空白則終止運行*/
if(Q->front==Q->rear) {
printf("隊列已空,無法刪除!\n");
exit(1);
}
/*使隊首指標指向下一個位置*/
Q->front=(Q->front+1)%Q->MaxSize;
/*返回隊首元素*/
return Q->queue[Q->front];
}
//4.讀取隊列首元素,不改變隊列狀態
ElemType PeekQueue(struct QueueSq* Q)
{
/*若隊列為空白則退出運行*/
/*若隊列為空白則終止運行*/
if(Q->front==Q->rear) {
printf("隊列已空,無法讀取!\n");
exit(1);
}
/*對首元素是隊列指標的下一個位置中的元素*/
return Q->queue[(Q->front+1)%Q->MaxSize];
}
//5.檢查一個隊列是否為空白,若是則返回1,否則返回0
int EmptyQueue(struct QueueSq* Q)
{
if(Q->front==Q->rear) return 1; else return 0;
}
//6.清空一個隊列,並釋放動態儲存裝置空間
void ClearQueue(struct QueueSq* Q)
{
if(Q->queue!=NULL){
free(Q->queue);
Q->queue=0;
Q->front=0;
Q->MaxSize=0;
}
}
void main()
{
struct QueueSq q;
int a[8]={3,8,5,17,9,30,15,22};
int i;
InitQueue(&q, 5);
for(i=0;i<8;i++) EnQueue(&q, a[i]);
printf("%d",OutQueue(&q));printf("%d\n",OutQueue(&q));
while(!EmptyQueue(&q)) printf("%d",OutQueue(&q));
printf("\n");
ClearQueue(&q);
}