C語言 隊列 鏈式結構 實現

一個C語言鏈式結構實現的隊列 mQueue (GCC編譯)。函數

  1 /**
  2 * @brief C語言實現的鏈式隊列
  3 * @author wid
  4 * @date 2013-10-31
  5 *
  6 * @note 若代碼存在 bug 或程序缺陷, 請留言反饋, 謝謝!
  7 */
  8 
  9 #include <stdio.h>
 10 #include <stdlib.h>
 11 
 12 #define TRUE 1
 13 #define FALSE 0
 14 
 15 typedef struct Point2D
 16 {
 17     int x;
 18     int y;
 19 }ElemType;      //元素結構
 20 
 21 typedef struct QNODE
 22 {
 23     ElemType *pe;
 24     struct QNODE *next;
 25 }QueueNode;     //隊列節點結構
 26 
 27 typedef struct MQUEUE
 28 {
 29     QueueNode *rear;        //隊列尾節點
 30     QueueNode *front;       //隊列頭節點
 31     int len;                //隊列長度
 32 }mQueue;
 33 
 34 //隊列方法聲明
 35 mQueue *CreateQueue();                          ///建立一個空隊列
 36 void DestroyQueue( mQueue *pQueue );            ///銷燬隊列 pQueue
 37 void ClearQueue( mQueue *pQueue );              ///置空隊列 pQueue
 38 int IsEmpty( mQueue *pQueue );                  ///是否爲空空隊列
 39 int GetLength( mQueue *pQueue );                ///獲取隊列長度
 40 int EnQueue( mQueue *pQueue, ElemType *pe );    ///將元素pe插入到隊尾
 41 int DeQueue( mQueue *pQueue, ElemType **pe );   ///將將隊頭元素出隊
 42 int GetHead( mQueue *pQueue, ElemType **pe );   ///獲取隊頭元素(不出隊)
 43 void ForEachQueue( mQueue *pQueue, void (*func)(ElemType *pe) );        ///從隊頭到隊尾依次執行func函數
 44 
 45 
 46 //隊列方法實現
 47 /**
 48 * @brief 建立一個空隊列
 49 *
 50 * @return 返回指向新建立的隊列的指針
 51 */
 52 mQueue *CreateQueue()
 53 {
 54     ///建立隊列
 55     mQueue *pQueue = (mQueue *)malloc( sizeof(mQueue) );
 56 
 57     ///令隊頭指向隊尾
 58     pQueue->front = pQueue->rear = (QueueNode *)malloc( sizeof(QueueNode) );
 59 
 60     ///隊尾的next節點指向NULL
 61     pQueue->rear->next = NULL;
 62 
 63     ///隊頭的next節點指向隊尾
 64     pQueue->front->next = pQueue->rear;
 65 
 66     ///初始化隊長爲 0
 67     pQueue->len = 0;
 68 
 69     return pQueue;
 70 }
 71 
 72 /**
 73 * @brief 銷燬隊列 pQueue
 74 *
 75 * @param pQueue 指向待銷燬的隊列
 76 */
 77 void DestroyQueue( mQueue *pQueue )
 78 {
 79     QueueNode *tmp = NULL;
 80 
 81     ///釋放隊列內元素
 82     while( pQueue->front != NULL )
 83     {
 84         tmp = pQueue->front->next;
 85         free( pQueue->front );
 86         pQueue->front = tmp;
 87     }
 88 
 89     ///釋放隊列
 90     free( pQueue );
 91 }
 92 
 93 /**
 94 * @brief 將隊列中的元素所有清除
 95 *
 96 * @param pQueue 指向待置空的隊列
 97 */
 98 void ClearQueue( mQueue *pQueue )
 99 {
100     QueueNode *tmp = NULL;
101 
102     ///釋放隊列內元素(保留一隊尾節點)
103     while( pQueue->front->next != NULL )
104     {
105         tmp = pQueue->front->next;
106         free( pQueue->front );
107         pQueue->front = tmp;
108     }
109 
110     pQueue->len = 0;
111 }
112 
113 /**
114 * @brief 是否爲空隊列
115 *
116 * @param pQueue 指向待檢測的隊列
117 *
118 * @return 若爲空則返回 TRUE, 不然返回 FALSE
119 */
120 int IsEmpty( mQueue *pQueue )
121 {
122     return pQueue->len == 0 ? TRUE : FALSE;
123 }
124 
125 /**
126 * @brief 獲取隊列長度
127 *
128 * @param pQueue 指向待獲取長度的隊列
129 *
130 * @return 返回隊列當前長度
131 */
132 int GetLength( mQueue *pQueue )
133 {
134     return pQueue->len;
135 }
136 
137 /**
138 * @brief 將元素pe插入到隊尾
139 *
140 * @param pQueue 指向待入隊的隊列
141 * @param pe 指向待插入的元素
142 *
143 * @return 插入成功則返回入隊後隊列的長度, 不然返回 -1
144 */
145 int EnQueue( mQueue *pQueue, ElemType *pe )
146 {
147     ///請求一個新節點
148     QueueNode *pNode = (QueueNode *)malloc( sizeof(QueueNode) );
149 
150     ///新節點的數據元素指向傳入的元素
151     pNode->pe = pe;
152 
153     ///新節點的next節點指向 NULL
154     pNode->next = NULL;
155 
156     ///隊尾的next節點指向新節點
157     pQueue->rear->next = pNode;
158 
159     ///令隊尾指向新節點
160     pQueue->rear = pNode;
161 
162     return ++pQueue->len;
163 }
164 
165 /**
166 * @brief 將隊頭元素出隊
167 *
168 * @param pQueue 指向待出隊的隊列
169 * @param pe 指向接收元素的指針的指針
170 *
171 * @return 成功出隊後返回出隊後隊列的長度, 不然返回 -1
172 */
173 int DeQueue( mQueue *pQueue, ElemType **pe )
174 {
175 
176     ///隊列是否爲空
177     if( pQueue->front == pQueue->rear )
178         return -1;
179 
180     ///獲得隊頭元素
181     *pe = pQueue->front->next->pe;
182 
183     ///令隊頭指向上一節點
184     QueueNode *tmp = pQueue->front;
185     pQueue->front = pQueue->front->next;
186     free( tmp );
187 
188     return --pQueue->len;
189 }
190 
191 /**
192 * @brief 獲取隊頭元素, 不出棧
193 *
194 * @param 指向待獲取隊頭元素的隊列
195 * @param 指向接收出棧元素的指針的指針
196 *
197 * @return 獲取成功則返回元素在隊列中的位置, 不然返回 -1, 且 *pe 指向 NULL
198 *
199 * @note 元素位置由 0 計起
200 */
201 int GetHead( mQueue *pQueue, ElemType **pe )
202 {
203     ///隊列是否爲空
204     if( pQueue->front == pQueue->rear )
205     {
206         *pe = NULL;
207         return -1;
208     }
209 
210     ///獲得隊頭元素
211     *pe = pQueue->front->next->pe;
212 
213     return pQueue->len - 1;
214 }
215 
216 /**
217 * @brief 從隊頭到隊尾對每一個元素依次執行 func 函數
218 *
219 * @param pQueue 指向待處理的隊列
220 * @param func 回調函數
221 */
222 void ForEachQueue( mQueue *pQueue, void (*func)(ElemType *pe) )
223 {
224     QueueNode *tmp = pQueue->front;
225 
226     ///遍歷執行 func
227     while( tmp != pQueue->rear && (tmp = tmp->next) )
228     {
229         func( tmp->pe );
230     }
231 }
232 
233 //測試
234 
235 /**
236 * @brief 輸出元素 pe
237 */
238 void display( ElemType *pe )
239 {
240     printf( "(%d,%d )", pe->x, pe->y );
241 }
242 
243 int main()
244 {
245     ///準備數據元素
246     ElemType pt1 = { 10, 10 };
247     ElemType pt2 = { 20, 20 };
248     ElemType pt3 = { 30, 30 };
249     ElemType pt4 = { 40, 40 };
250     ElemType pt5 = { 50, 50 };
251 
252     ///測試 CreateQueue
253     mQueue *pque = CreateQueue();
254 
255     ///測試 IsEmpty、GetLength
256     if( IsEmpty(pque) == TRUE )
257         printf( "隊列當前長度:%d, 是否爲空隊列:%d\n", GetLength(pque), IsEmpty(pque) );
258 
259     ///測試 EnQueue
260     EnQueue( pque, &pt1 );
261     if( IsEmpty(pque) != TRUE )
262         printf( "入隊1元素後隊列當前長度:%d, 是否爲空隊列:%d\n", GetLength(pque), IsEmpty(pque) );
263 
264     ///測試 ClearQueue
265     ClearQueue( pque );
266     printf( "清空隊列, 當前長度:%d\n", GetLength(pque) );
267 
268     ///入隊5元素
269     printf( "\n連續入隊5元素..\n" );
270     EnQueue( pque, &pt1 );
271     EnQueue( pque, &pt2 );
272     EnQueue( pque, &pt3 );
273     EnQueue( pque, &pt4 );
274     EnQueue( pque, &pt5 );
275 
276     ///測試 ForEachQueue
277     printf( "測試 ForEachQueue:" );
278     ForEachQueue( pque, display );
279 
280     ///測試 DeQueue
281     ElemType *p = NULL;
282     if( DeQueue(pque, &p) != -1 )
283         printf( "\n\n測試DeQueue, 出隊元素爲:(%d,%d), 出隊後隊列長度:%d\n", p->x, p->y, GetLength(pque) );
284 
285     ///測試 GetHead
286     if( GetHead(pque, &p) != -1 )
287         printf( "\n測試GetHead, Head元素爲(%d,%d)\n", p->x, p->y );
288 
289     ///所有出隊
290     printf( "\n執行所有出隊...\n" );
291     while( DeQueue(pque, &p) != -1 )
292     {
293         printf( "當前出隊:(%d,%d), 隊列剩餘長度:%d, 是否爲空隊列%d\n", p->x, p->y, GetLength(pque), IsEmpty(pque) );
294     }
295 
296     ///銷燬隊列
297     printf( "\n銷燬隊列...\n" );
298     DestroyQueue( pque );
299 
300     return 0;
301 }

運行測試:測試

 

若代碼存在 bug 或程序缺陷, 請留言反饋, 謝謝。                                                                                                                                                                                                                                                                                                                                                            spa

相關文章
相關標籤/搜索