一個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