C語言 隊列 順序結構 實現

一個可以自動擴容的順序結構的隊列 ArrQueue (GCC編譯)。函數

 

  1 /**
  2 * @brief C語言順序結構隊列的實現
  3 * @author wid
  4 * @date 2013-10-30
  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
 22 {
 23     ElemType **rear;    //隊尾
 24     ElemType *front;    //隊頭
 25     int len;            //隊列長度
 26     int size;           //隊列總容量
 27 }ArrQueue;      //隊列結構
 28 
 29 //聲明隊列方法
 30 
 31 ArrQueue *CreateQueue( int nLen );          //建立初始長度爲 nLen 隊列
 32 void DestroyQueue( ArrQueue *pQueue );      //銷燬隊列pQueue
 33 void ClearQueue( ArrQueue *pQueue );        //清空隊列內元素
 34 int GetLength( ArrQueue *pQueue );          //獲取隊列長度
 35 int GetSize( ArrQueue *pQueue );            //獲取隊列總容量
 36 int IsEmpty( ArrQueue *pQueue );            //檢測隊列是否爲空
 37 int GetHead( ArrQueue *pQueue, ElemType **pe );      //獲取隊頭元素
 38 int EnQueue( ArrQueue *pQueue, ElemType *pe );       //將元素插入到隊尾
 39 int DeQueue( ArrQueue *pQueue, ElemType **pe );      //將隊頭元素出隊
 40 void ForEachQueue( ArrQueue *pQueue, void (*func)(ElemType *pe) );      //從對尾到隊頭依次執行 func
 41 
 42 //隊列方法實現
 43 
 44 /**
 45 * @brief 建立初始長度爲 nLen 的隊列
 46 *
 47 * @param nLen 隊列的初始長度
 48 *
 49 * @return 返回指向新建立的隊列的指針
 50 */
 51 ArrQueue *CreateQueue( int nLen )
 52 {
 53     ArrQueue *pQueue = (ArrQueue *)malloc( sizeof(ArrQueue) );
 54     pQueue->rear = (ElemType **)calloc( nLen, sizeof(ElemType **) );
 55     pQueue->front = pQueue->rear[0];
 56     pQueue->len = 0;
 57     pQueue->size = nLen;
 58 
 59     return pQueue;
 60 }
 61 
 62 /**
 63 * @brief 銷燬隊列
 64 *
 65 * @param pQueue 指向待銷燬的隊列的指針
 66 */
 67 void DestroyQueue( ArrQueue *pQueue )
 68 {
 69     free( pQueue->rear );
 70     free( pQueue );
 71 
 72     pQueue = NULL;
 73 }
 74 
 75 /**
 76 * @brief 清空隊列內元素
 77 */
 78 void ClearQueue( ArrQueue *pQueue )
 79 {
 80     pQueue->front = pQueue->rear[0];
 81 
 82     pQueue->len = 0;
 83 }
 84 
 85 /**
 86 * @brief 獲取隊列長度
 87 *
 88 * @param 指向待獲取長度的隊列的指針
 89 *
 90 * @return 返回隊列當前長度
 91 */
 92 int GetLength( ArrQueue *pQueue )
 93 {
 94     return pQueue->len;
 95 }
 96 
 97 /**
 98 * @brief 獲取隊列總容量
 99 *
100 * @param pQueue 指向待獲取容量的隊列
101 *
102 * @return 返回隊列當前總容量
103 */
104 int GetSize( ArrQueue *pQueue )
105 {
106     return pQueue->size;
107 }
108 
109 /**
110 * @brief 檢測隊列是否爲空
111 *
112 * @param pQueue 指向待檢測的隊列
113 *
114 * @return 若爲空, 則返回 TRUE, 不然返回 FALSE
115 */
116 int IsEmpty( ArrQueue *pQueue )
117 {
118     return pQueue->len == 0 ? TRUE : FALSE;
119 }
120 
121 /**
122 * @brief 獲取隊頭元素
123 *
124 * @param pQueue 指向待獲取隊頭元素的隊列
125 *
126 * @param pe 指向接收元素的指針的指針
127 *
128 * @return 返回隊頭在隊列中的位置(位置由 0 計起)
129 */
130 int GetHead( ArrQueue *pQueue, ElemType **pe )
131 {
132     if( pQueue->len == 0 )
133     {
134         *pe = NULL;
135         return -1;
136     }
137 
138     *pe = pQueue->rear[pQueue->len-1];
139 
140     return pQueue->len-1;
141 }
142 
143 /**
144 * @brief 將元素 pe 插入到隊尾
145 *
146 * @param pQueue 指向待插入元素的隊列
147 * @param pe 指向待插入的元素
148 *
149 * @return 返回成功插入後隊列的長度
150 */
151 int EnQueue( ArrQueue *pQueue, ElemType *pe )
152 {
153     ///檢測是否須要擴容
154     if( pQueue->len == pQueue->size )
155     {   //須要擴容
156         pQueue->rear = realloc( pQueue->rear, 2 * pQueue->size * sizeof(ElemType *) );
157         pQueue->size = 2 * pQueue->size;
158     }
159 
160     int i = 0;
161     for( i = pQueue->len; i > 0; --i )
162     {
163         pQueue->rear[i] = pQueue->rear[i-1];
164     }
165     pQueue->rear[0] = pe;
166     pQueue->front = pQueue->rear[pQueue->len];
167 
168     return ++pQueue->len;
169 }
170 
171 /**
172 * @brief 將隊頭元素出隊
173 *
174 * @param pQueue 指向待出隊的隊列
175 * @param pe 指向接收元素的指針的指針
176 *
177 * @return 成功出隊則返回出隊後隊列的長度, 不然返回 -1
178 */
179 int DeQueue( ArrQueue *pQueue, ElemType **pe )
180 {
181     if( pQueue->len == 0 )
182     {
183         *pe = NULL;
184         return -1;
185     }
186     *pe = pQueue->front;
187     --pQueue->len;
188     pQueue->front = pQueue->rear[pQueue->len-1];
189 
190     return pQueue->len;
191 }
192 
193 /**
194 * @brief 從隊尾到隊頭每一個元素一次執行 func
195 *
196 * @param pQueue 指向待處理的隊列
197 * @param  func 回調函數指針
198 */
199 void ForEachQueue( ArrQueue *pQueue, void (*func)(ElemType *pe) )
200 {
201     int i = 0;
202     for( i = 0; i < pQueue->len; ++i )
203     {
204         func( pQueue->rear[i] );
205     }
206 }
207 
208 //測試
209 void display( ElemType *pe )
210 {
211     printf( "(%d,%d) ", pe->x, pe->y );
212 }
213 
214 int main()
215 {
216     ElemType t1 = {10, 20};
217     ElemType t2 = {30, 40};
218     ElemType t3 = {50, 60};
219     ElemType t4 = {70, 80};
220     ElemType t5 = {99, 99};
221 
222     ///測試 CreateQueue
223     ArrQueue *pque = CreateQueue( 3 );
224 
225     ///測試入隊
226     EnQueue( pque, &t1 );
227     EnQueue( pque, &t2 );
228     EnQueue( pque, &t3 );
229     EnQueue( pque, &t4 );
230     EnQueue( pque, &t5 );
231 
232     ///測試 ForEachQueue
233     ForEachQueue( pque, display );
234 
235     ///測試 IsEmpty、GetSize、GetLength
236     if( IsEmpty( pque ) != TRUE )
237         printf( "\n隊列總容量:%d, 當前長度:%d\n", GetSize(pque), GetLength(pque) );
238 
239     ///測試所有出隊
240     printf( "\n測試所有出隊:\n" );
241     ElemType *p;
242     while( DeQueue( pque, &p ) != -1 )
243     {
244         printf( "當前出隊:(%d,%d), 剩餘隊列長爲:%d\n", p->x, p->y, GetLength(pque) );
245     }
246 
247     ///測試 ClearQueue
248     printf( "\n再次入隊2元素..\n" );
249     EnQueue( pque, &t1 );
250     EnQueue( pque, &t2 );
251     ForEachQueue( pque, display );
252     printf( "\n清空隊列..\n" );
253     ClearQueue( pque );
254     printf( "隊列總容量:%d, 當前長度:%d\n", GetSize(pque), GetLength(pque) );
255 
256     ///測試 GetHead
257     printf( "\n再次入隊2元素..\n" );
258     EnQueue( pque, &t1 );
259     EnQueue( pque, &t2 );
260     ForEachQueue( pque, display );
261     GetHead( pque, &p );
262     printf( "\n獲取隊頭元素:(%d,%d)\n", p->x, p->y );
263     printf( "隊列總容量:%d, 當前長度:%d\n", GetSize(pque), GetLength(pque) );
264 
265     ///銷燬隊列
266     DestroyQueue( pque );
267 
268     return 0;
269 }

 

測試運行:測試

 

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

相關文章
相關標籤/搜索