1 #include <stdio.h> 2 #include <stdlib.h> 3 4 #define OK 1 5 #define ERR 2 6 #define TRUE 1 7 #define FALSE 0 8 9 typedef int status; //定義函數返回的狀態,OK & ERR 10 typedef char datatype; //定義隊列中每個元素的數據類型,這里暫定為字符型 11 12 typedef struct LinkQueue_anon{ 13 datatype data; //數據區 14 struct LinkQueue_anon * next; //指針區 15 } LinkQueue; 16 typedef struct { 17 LinkQueue * front, * rear; 18 /* 19 創建隊列的游標,保存着隊列的頭尾指針所指向的結點 20 front指向隊列的第一個結點(隊頭),rear指向隊列的最后一個結點(隊尾) 21 規定: 22 當front=rear=NULL時,表示隊列為空 23 當front=rear!=NULL時,表示隊列只有一個元素 24 */ 25 }LinkQueueCursor; 26 27 /* 函數原型,隊列的基本操作,與棧相同 */ 28 LinkQueueCursor *createLinkQueue(datatype first_node_value); 29 status isEmpty(LinkQueueCursor *L); 30 void clear(LinkQueueCursor *L); 31 datatype getTop(LinkQueueCursor *L); 32 int getLength(LinkQueueCursor *L); 33 status push(LinkQueueCursor *L, datatype node_to_push); 34 datatype pop(LinkQueueCursor *L); 35 void showQueue(LinkQueueCursor *L); 36 37 int main(){ 38 /* 測試 */ 39 LinkQueueCursor * mycursor; 40 mycursor=createLinkQueue('1'); //創建一個游標,同時入隊一個元素,其值為'1' 41 printf("isEmpty = %d\n",isEmpty(mycursor)); 42 printf("Length = %d\n",getLength(mycursor)); 43 push(mycursor,'a'); 44 push(mycursor,'b'); 45 push(mycursor,'c'); 46 push(mycursor,'d'); 47 printf("isEmpty = %d\n",isEmpty(mycursor)); 48 printf("Length = %d\n",getLength(mycursor)); 49 showQueue(mycursor); 50 putchar('\n'); 51 printf("pop = %c\n",pop(mycursor)); 52 printf("pop = %c\n",pop(mycursor)); 53 printf("getTop = %c\n",getTop(mycursor)); 54 printf("isEmpty = %d\n",isEmpty(mycursor)); 55 printf("Length = %d\n",getLength(mycursor)); 56 showQueue(mycursor); 57 putchar('\n'); 58 clear(mycursor); 59 printf("isEmpty = %d\n",isEmpty(mycursor)); 60 printf("Length = %d\n",getLength(mycursor)); 61 62 return 0; 63 } 64 65 LinkQueueCursor *createLinkQueue(datatype first_node_value){ 66 LinkQueueCursor *tmp_cur; 67 LinkQueue *tmp; 68 tmp_cur=malloc(sizeof(LinkQueueCursor)); //void*類型指針能自動轉為其他類型的指針 69 tmp=malloc(sizeof(LinkQueue)); 70 tmp_cur->front=tmp_cur->rear=tmp; //初始化游標 71 tmp->data=first_node_value; //初始化數據區 72 tmp->next=NULL; //初始化指針區 73 return tmp_cur; 74 } 75 status isEmpty(LinkQueueCursor *L){ 76 if (L->front==L->rear && L->front==NULL) 77 return TRUE; 78 else 79 return FALSE; 80 } 81 void clear(LinkQueueCursor *L){ 82 LinkQueue * p,* q; 83 if (isEmpty(L)) return; //空隊列,不需要clear,所以直接返回 84 if (L->front==L->rear && L->front!=NULL){ //只有一個元素的隊列,front和rear都指向這個元素 85 free(L->front); 86 L->front=L->rear=NULL; //把隊列設為空 87 return; 88 } 89 /* 當隊列的元素大於1時 */ 90 p=L->front; //p指向當前要被刪除的結點 91 while (p){ 92 //當p不為NULL繼續循環 93 q=p->next; //q指向p的下一個結點 94 free(p); 95 p=q; //交換 96 } 97 L->front=L->rear=NULL; //把隊列設為空 98 99 } 100 datatype getTop(LinkQueueCursor *L){ 101 return L->front->data; //直接返回隊頭的數據即可 102 } 103 int getLength(LinkQueueCursor *L){ 104 int i=0; 105 LinkQueue * p; 106 if (isEmpty(L)) return 0; //空隊列,返回0 107 if (L->front==L->rear && L->front!=NULL) return 1; //規定:front=rear,說明隊列只有一個元素 108 /* 隊列的長度大於1時 */ 109 p=L->front; 110 while (p!=L->rear){ //還沒到rear(隊尾)則繼續循環 111 i++; p=p->next; 112 } 113 return i+1; 114 /* 115 上面的【隊列的長度大於1時】還能用下面的等價代碼代替 116 p=L->front; 117 while (p){ //p不為NULL則繼續循環,因為rear(隊尾)結點的next(指針區)一定是NULL 118 i++; p=p->next; 119 } 120 return i; 121 */ 122 } 123 status push(LinkQueueCursor *L, datatype node_to_push){ 124 //node_to_insert表示想要在隊尾處入隊的元素 125 LinkQueue * s=malloc(sizeof(LinkQueue)); 126 s->data=node_to_push; //初始化新入隊的元素 127 s->next=NULL; 128 if (isEmpty(L)==TRUE){ 129 //插入到空隊列 130 L->front=L->rear=s; //入隊,當隊列只有一個元素時,規定front和rear都指向這個元素 131 }else{ 132 //插入到已存在元素的隊列 133 L->rear->next=s; //入隊,將新元素附在rear指向的結點的后面 134 L->rear=s; //rear后移,即將它指向新元素 135 } 136 return OK; 137 } 138 datatype pop(LinkQueueCursor *L){ 139 //出隊,即將隊頭刪除 140 datatype v; 141 LinkQueue * s; 142 if (isEmpty(L)) return (datatype)ERR; //空隊列 143 if (L->front==L->rear && L->front!=NULL){ //隊列只有一個元素 144 v=L->front->data; //把這個元素的值賦值給臨時變量 145 free(L->front); //刪除這個元素 146 L->front=L->rear=NULL; //把隊列設置為空 147 }else{ 148 v=L->front->data; //將要刪除的元素的值先賦值給臨時變量 149 s=L->front; //將要刪除的元素先賦值給臨時變量 150 L->front=L->front->next; //將游標所保存的front后移到下個結點(元素) 151 free(s); //刪除原來的頭結點(元素) 152 } 153 return v; //返回出隊結點(元素)的值 154 } 155 void showQueue(LinkQueueCursor *L){ 156 int i; 157 int total=getLength(L); 158 LinkQueue * p; 159 p=L->front; 160 for (i=0; i<total; i++){ 161 printf("%c\t",p->data); p=p->next; 162 } 163 } 164 /* 165 隊列的定義:只允許在一端進行插入,另一端進行刪除的線性表,也是一種操作受限的線性表 166 一般,把允許插入的一端叫做隊尾,允許刪除的一端叫做隊頭 167 不含任何元素的隊列就是空隊 168 所以,隊列又稱先進先出(First in First out)的線性表 169 隊列的鏈式存儲其實就是線性表中的單鏈表,只不過它只能尾進頭出 170 */ 171 /* 環境: Code::Blocks with GCC 5.1 */
運行截圖: