1. 程式人生 > >資料機構 C語言實現佇列(含程式碼詳解 易懂)

資料機構 C語言實現佇列(含程式碼詳解 易懂)

/* 數學模型參照《大話資料結構》佇列部分   !!!取餘運算實現佇列迴圈!!! */
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>


#define OK 1 
#define ERROR 0
#define TURE 1
#define FALSE 0
#define MAXSIZE 20 /* 佇列最大的成員個數 即陣列的長度 */


typedef int Status;
typedef int QElemType;


/* 迴圈佇列的順序儲存結構 */ /* 結構體 作用 構成一個新的資料結構 */
typedef struct
{
QElemType data[MAXSIZE];
int front;/* 頭指標 指向當前元素 而不是下一個 說是指標,其實就是陣列下標 */
int rear; /* 尾指標 指向元素的下一個位置 這樣可以與第幾個的意思吻合 */
}SqQueue;


/* 初始化一個空的佇列 */
Status InitQueue(SqQueue *Q)/* 改變 在主函式的 佇列中元素的數值 故形參用指標 */
{
Q -> front = 0;
Q -> rear = 0;
return OK;
}


/* 將佇列清空 */
Status ClearQueue(SqQueue *Q)
{
Q -> front = 0;
Q -> rear = 0;
return OK;
}


/* 判斷佇列是否為空 是則返回Ture */
Status QueueEmpty(SqQueue Q)/* 不改變 在主函式的 佇列中元素的數值,僅copy該佇列,對相關元素進行判斷操作 */
{
if(Q.front == Q.rear)
return TURE;
else 
return FALSE;
}


/* 返回佇列中元素的個數 */
Status QueueLength(SqQueue Q)
{
return ( (Q.rear - Q.front + MAXSIZE) % MAXSIZE );
}


/* 返回隊首元素 */
Status FrontQueue(SqQueue Q,QElemType *e)/* *e 作用 中轉隊首元素的數值 */
{
if(Q.front == Q.rear)
return ERROR;
*e = Q.data[Q.front];/* 分清 是copy判斷佇列狀態 還是中轉or改變佇列元素  前者形參正常結構型別 後者指標  */
return OK;
}


/* 返回隊尾元素 */
Status RearQueue(SqQueue Q,QElemType *e)
{
if(Q.front == Q.rear)
return ERROR;
*e = Q.data[Q.rear-1];/* 假設隊尾元素是a0 那麼Q.rear實際指向a1 */
return OK;
}


/* 佇列未滿 隊尾插入操作  插入一個元素 隊尾指標+1 */
Status InsertQueue(SqQueue *Q,QElemType e)
{
if( (Q -> rear + 1) % MAXSIZE == Q -> front ) 
return ERROR;
Q -> data[Q -> rear] = e;
Q -> rear = (Q -> rear + 1) % MAXSIZE;/* 若到了陣列最後 則轉到頭部 */
return OK;
}


/* 佇列未空 隊首刪除操作 並返回刪除的那個元素的數值  與插入類似,每刪除一個,隊首指標+1 */
Status DeleteQueue(SqQueue *Q,QElemType *e)
{
if( Q -> rear == Q -> front ) 
return ERROR;
*e = Q -> data[Q -> front];
Q -> front = (Q -> front + 1) % MAXSIZE;/* 若到了陣列最後 則轉到頭部 */
return OK;
}


Status visit(QElemType c)
{
printf("%d ",c);
return OK;
}


/* 遍歷整個佇列 從頭到尾輸出每一個元素的數值 */
Status TraverseQueue(SqQueue Q)
{
int j;
j = QueueEmpty(Q);
if( j == TURE)
printf("該佇列為空佇列\n");

int i = Q.front;
while(i != Q.rear)
{
visit(Q.data[i]);
i = (i+1) % MAXSIZE;
}
printf("\n");
return OK;
}


int main()
{
int a,b,Qlength;
SqQueue Q;
QElemType e,f;

/* 佇列初始化 */
a = InitQueue(&Q);
if(a == OK)
printf("佇列初始化成功\n");
else 
return ERROR;
/* 判斷佇列是否為空 */
a = QueueEmpty(Q);
if(a == TURE)
printf("佇列為空\n");
else
return ERROR;


/* 通過插入構造新佇列 */
int i;
printf("請輸入你想插入的元素的個數:%d 佇列長度為:%d 其中有一個元素存在且為空\n",MAXSIZE-1,MAXSIZE);
for(i = 1;i <= (MAXSIZE - 1);i++)
{
e = i;
InsertQueue(&Q,e);
}
/* 遍歷新佇列 */
TraverseQueue(Q);


/* 求取佇列長度 */
Qlength = QueueLength(Q);
printf("佇列長度為:%d\n",Qlength);


/* 返回隊首元素 */
a = FrontQueue(Q,&e);
if(a == OK)
printf("返回隊首元素操作成功\n");
else
return ERROR;
printf("隊首元素:%d\n",e);


/* 返回隊尾元素 */
a = RearQueue(Q,&e);
if(a == OK)
printf("返回隊尾元素操作成功\n");
else
return ERROR;
printf("隊尾元素:%d\n",e);

printf("是否執行接下來的刪除操作?yes or no(yes 輸入1  no 輸入0)\n");
scanf("%d",&b);
switch(b)
{
case 0:break;
case 1:
/* 刪除隊首的兩個元素 */
DeleteQueue(&Q,&e);
printf("第一次刪除操作返回的隊首元素:%d\n",e);
DeleteQueue(&Q,&f);
printf("第二次刪除操作返回的隊首元素:%d\n",f);
/* 遍歷此時的佇列 */
TraverseQueue(Q);
break;
}

ClearQueue(&Q);
a = QueueEmpty(Q);
if(a == TURE)
printf("佇列為空\n");
else
return ERROR;

printf("\n 您已經完成佇列的複習 :) \n");
return 0;
}