隊列的鏈式存儲結構(C語言實現)


  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 */

運行截圖:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM