《資料結構》(C語言版)——迴圈佇列――――佇列的順序儲存結構
阿新 • • 發佈:2019-01-31
/* run this program using the console pauser or add your own getch, system("pause") or input loop */ // 用到的庫檔案 #include <stdio.h> // printf();scanf() #include <stdlib.h> // exit() #include <malloc.h> // malloc() #include <time.h> // srand((unsigned)time(NULL)); // 函式結果狀態程式碼 #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #define OVERFLOW -2 // Status是函式的型別,其值是函式結果狀態程式碼 typedef int Status; // #define ElemType int // 也可以用巨集定義確定ElemType型別 typedef char QElemType; // -----迴圈佇列――――佇列的順序儲存結構----- #define MAXQSIZE 100 // 最大佇列長度 typedef struct { // 佇列鏈式結構 QElemType *base; // 初始化的動態分配儲存空間 int front; // 頭指標,若佇列不空,指向佇列頭元素 int rear; // 尾指標,若佇列不空,指向佇列尾元素的下一個位置 } SqQueue; // 操作結果:構造一個空佇列Q。 Status InitQueue(SqQueue &Q) { Q.base = (QElemType*)malloc(MAXQSIZE * sizeof(QElemType)); if(!Q.base) // 儲存分配失敗 exit(OVERFLOW); // exit(-2)程式異常退出 Q.front = Q.rear = 0; return OK; }// InitQueue // 操作結果:銷燬佇列Q,Q不再存在。 Status DestroyQueue(SqQueue &Q) { Q.front = Q.rear = 0; free(Q.base); return OK; }// DestroyQueue // 操作結果:把Q置為空佇列。 Status ClearQueue(SqQueue &Q) { Q.front = Q.rear = 0; return OK; }// ClearQueue // 操作結果:若Q為空佇列,返回TRUE,否則返回FALSE Status QueueEmpty(SqQueue Q) { if(Q.front == Q.rear) return TRUE; // 返回1 else return FALSE; // 返回0 }// QueueEmpty // 操作結果:返回Q的元素個數,即佇列的長度。 int QueueLength(SqQueue Q) { return (Q.rear - Q.front + MAXQSIZE) % MAXQSIZE; }// QueueLength // 操作結果:若Q為非空佇列,則用e返回Q的隊頭元素。 Status GetHead(SqQueue Q, QElemType &e) { if(Q.front == Q.rear) return ERROR; // 空佇列 e = Q.base[Q.front]; // 取隊頭元素 printf("獲取的隊頭元素:%c\n", e); return OK; }// GetHead // 操作結果:插入元素e為Q的新的隊尾元素。 Status EnQueue(SqQueue &Q, QElemType e) { // 少用一個元素空間,約定以“佇列頭指標在佇列尾指標的下一位置上”作為佇列滿的標誌。 if((Q.rear + 1) % MAXQSIZE == Q.front) return ERROR; // 佇列滿 Q.base[Q.rear] = e; // 插入元素e Q.rear = (Q.rear+1)%MAXQSIZE; // rear後移 printf("插入的隊尾元素:%c\n", e); return OK; }// EnQueue // 操作結果:刪除Q的隊頭元素,並用e返回其值。 Status DeQueue(SqQueue &Q, QElemType &e) { if(Q.front == Q.rear) return ERROR; // 空佇列 e = Q.base[Q.front]; Q.front = (Q.front+1)%MAXQSIZE; // front後移 printf("刪除的隊頭元素:%c\n", e); return OK; } Status visit(QElemType e) { printf("%c -> ", e); return OK; }// DeQueue // 操作結果:從 隊頭到隊尾,依次對Q的每個資料元素呼叫函式visit()。一旦vistit()失敗,剛操作失敗。 Status QueueTraverse(SqQueue Q, Status (*pfn_visit)(QElemType)) { if(Q.front == Q.rear) { printf("佇列為空!\n"); return ERROR; // 空佇列 } int i = Q.front; // i指向隊頭元素下標 while(i != Q.rear) { visit(Q.base[i]); i = (i+1) % MAXQSIZE; } printf("\n"); return OK; }// QueueTraverse int main() { SqQueue Q; // 構造空佇列 if(InitQueue(Q)) { // 插入元素 for(int i=0; i<26; i++) EnQueue(Q, 'A' + i); } // 求佇列長 printf("佇列的大小:%d\n", QueueLength(Q)); // 返回佇列的隊頭元素 QElemType e; if(GetHead(Q, e)) QueueTraverse(Q, visit); // 刪除佇列的隊頭元素 if(DeQueue(Q, e)) QueueTraverse(Q, visit); // 判空 if(QueueEmpty(Q)) printf("佇列為空。\n"); else printf("佇列非空。\n"); // 置空 ClearQueue(Q); QueueTraverse(Q, visit); // 判空 if(QueueEmpty(Q)) printf("佇列為空。\n"); else printf("佇列非空。\n"); // 銷燬 DestroyQueue(Q); return 0; }