概要
本章和介紹"棧"時的流程一樣,先對隊列進行介紹,然后分別給出隊列的C、C++和Java三種語言的實現。內容包括:
1. 隊列的介紹
2. 隊列的C實現
3. 隊列的C++實現
4. 隊列的Java實現
轉載請注明出處:http://www.cnblogs.com/skywang12345/p/3562279.html
更多內容: 數據結構與算法系列 目錄
隊列的介紹
隊列(Queue),是一種線性存儲結構。它有以下幾個特點:
(01) 隊列中數據是按照"先進先出(FIFO, First-In-First-Out)"方式進出隊列的。
(02) 隊列只允許在"隊首"進行刪除操作,而在"隊尾"進行插入操作。
隊列通常包括的兩種操作:入隊列 和 出隊列。
1. 隊列的示意圖
隊列中有10,20,30共3個數據。
2. 出隊列
出隊列前:隊首是10,隊尾是30。
出隊列后:出隊列(隊首)之后。隊首是20,隊尾是30。
3. 入隊列
入隊列前:隊首是20,隊尾是30。
入隊列后:40入隊列(隊尾)之后。隊首是20,隊尾是40。
下面介紹隊列的實現,分別介紹C/C++/Java三種實現
隊列的C實現
共介紹4種C語言實現。
1. C語言實現一:數組實現的隊列,並且只能存儲int數據。
2. C語言實現二:單向鏈表實現的隊列,並且只能存儲int數據。
3. C語言實現三:雙向鏈表實現的隊列,並且只能存儲int數據。
4. C語言實現四:雙向鏈表實現的隊列,能存儲任意類型的數據。
1. C語言實現一:數組實現的隊列,並且只能存儲int數據
實現代碼(array_queue.c)

1 #include <stdio.h> 2 #include <malloc.h> 3 4 /** 5 * C 語言: 數組實現的隊列,只能存儲int數據。 6 * 7 * @author skywang 8 * @date 2013/11/07 9 */ 10 11 // 保存數據的數組 12 static int *arr=NULL; 13 // 隊列的實際大小 14 static int count; 15 16 // 創建“隊列” 17 int create_array_queue(int sz) 18 { 19 arr = (int *)malloc(sz*sizeof(int)); 20 if (!arr) 21 { 22 printf("arr malloc error!"); 23 return -1; 24 } 25 count = 0; 26 27 return 0; 28 } 29 30 // 銷毀“隊列” 31 int destroy_array_queue() 32 { 33 if (arr) 34 { 35 free(arr); 36 arr = NULL; 37 } 38 39 return 0; 40 } 41 42 // 將val添加到隊列的末尾 43 void add(int val) 44 { 45 arr[count++] = val; 46 } 47 48 // 返回“隊列開頭元素” 49 int front() 50 { 51 return arr[0]; 52 } 53 54 // 返回並刪除“隊列開頭元素” 55 int pop() 56 { 57 int i = 0;; 58 int ret = arr[0]; 59 60 count--; 61 while (i++<count) 62 arr[i-1] = arr[i]; 63 64 return ret; 65 } 66 67 // 返回“隊列”的大小 68 int size() 69 { 70 return count; 71 } 72 73 // 返回“隊列”是否為空 74 int is_empty() 75 { 76 return count==0; 77 } 78 79 void main() 80 { 81 int tmp=0; 82 83 // 創建“隊列” 84 create_array_queue(12); 85 86 // 將10, 20, 30 依次推入隊列中 87 add(10); 88 add(20); 89 add(30); 90 91 // 將“隊列開頭的元素”賦值給tmp,並刪除“該元素” 92 tmp = pop(); 93 printf("tmp=%d\n", tmp); 94 95 // 只將“隊列開頭的元素”賦值給tmp,不刪除該元素. 96 tmp = front(); 97 printf("tmp=%d\n", tmp); 98 99 add(40); 100 101 // 打印隊列 102 printf("is_empty()=%d\n", is_empty()); 103 printf("size()=%d\n", size()); 104 while (!is_empty()) 105 { 106 printf("%d\n", pop()); 107 } 108 109 // 銷毀隊列 110 destroy_array_queue(); 111 }
運行結果:
tmp=10 tmp=20 is_empty()=0 size()=3 20 30 40
結果說明:該示例中的隊列,是通過"數組"來實現的!
由於代碼中已經給出了詳細了注釋,這里就不再對函數進行說明了。僅對主函數main的邏輯進行簡單介紹。
(01) 在主函數main中,先將 "10, 20, 30"依次入隊列。此時,隊列的數據是: 10 --> 20 --> 30
(02) 接着通過pop()返回隊首元素;pop()操作並不會改變隊列中的數據。此時,隊列的數據依然是: 10 --> 20 --> 30
(03) 接着通過front()返回並刪除隊首元素。front()操作之后,隊列的數據是: 10 --> 30
(04) 接着通過add(40)將40入隊列。add(40)操作之后,隊列中的數據是: 10 --> 20 --> 40
2. C語言實現二:單向鏈表實現的隊列,並且只能存儲int數據
實現代碼(slink_queue.c)

1 #include <stdio.h> 2 #include <malloc.h> 3 4 /** 5 * C 語言: 單鏈表實現“隊列”,只能存儲int數據。 6 * 7 * @author skywang 8 * @date 2013/11/07 9 */ 10 11 // 單鏈表節點 12 struct node { 13 int val; 14 struct node* next; 15 }; 16 17 // 表頭 18 static struct node *phead=NULL; 19 20 // 創建節點,val為節點值 21 static struct node* create_node(val) 22 { 23 struct node *pnode=NULL; 24 pnode = (struct node*)malloc(sizeof(struct node)); 25 if (!pnode) 26 return NULL; 27 pnode->val = val; 28 pnode->next = NULL; 29 30 return pnode; 31 } 32 33 // 銷毀單向鏈表 34 static int destroy_single_link() 35 { 36 struct node *pnode=NULL; 37 38 while (phead != NULL) 39 { 40 pnode = phead; 41 phead = phead->next; 42 free(pnode); 43 } 44 return 0; 45 } 46 47 // 將val添加到隊列的末尾 48 static void add(int val) 49 { 50 if (!phead) 51 { 52 phead = create_node(val); 53 return ; 54 } 55 56 struct node *pnode = create_node(val); 57 struct node *pend = phead; 58 while (pend->next) 59 pend = pend->next; 60 61 pend->next = pnode; 62 } 63 64 // 返回“隊列開頭元素” 65 int front() 66 { 67 return phead->val; 68 } 69 70 // 返回並刪除“隊列開頭元素” 71 static int pop() 72 { 73 int ret = phead->val; 74 struct node *pnode = phead; 75 76 phead = phead->next; 77 free(pnode); 78 79 return ret; 80 } 81 82 // 返回鏈表中節點的個數 83 static int size() 84 { 85 int count=0; 86 struct node *pend = phead; 87 88 while (pend) 89 { 90 pend = pend->next; 91 count++; 92 } 93 94 return count; 95 } 96 97 // 鏈表是否為空 98 static int is_empty() 99 { 100 return size()==0; 101 } 102 103 void main() 104 { 105 int tmp=0; 106 107 // 將10, 20, 30 依次加入到隊列中 108 add(10); 109 add(20); 110 add(30); 111 112 // 將“隊列開頭元素”賦值給tmp,並刪除“該元素” 113 tmp = pop(); 114 printf("tmp=%d\n", tmp); 115 116 // 只將“隊列開頭的元素”賦值給tmp,不刪除該元素. 117 tmp = front(); 118 printf("tmp=%d\n", tmp); 119 120 add(40); 121 122 printf("is_empty()=%d\n", is_empty()); 123 printf("size()=%d\n", size()); 124 while (!is_empty()) 125 { 126 printf("%d\n", pop()); 127 } 128 129 // 銷毀隊列 130 destroy_single_link(); 131 }
代碼說明:"運行結果" 以及 "主函數main的邏輯"都和"C語言實現一"的一樣。不同的是,該示例中的隊列是通過單向鏈表實現的。
3. C語言實現三:雙向鏈表實現的隊列,並且只能存儲int數據
實現代碼
雙向鏈表的頭文件(double_link.h)

1 #ifndef _DOUBLE_LINK_H 2 #define _DOUBLE_LINK_H 3 4 // 新建“雙向鏈表”。成功,返回表頭;否則,返回NULL 5 extern int create_dlink(); 6 // 撤銷“雙向鏈表”。成功,返回0;否則,返回-1 7 extern int destroy_dlink(); 8 9 // “雙向鏈表是否為空”。為空的話返回1;否則,返回0。 10 extern int dlink_is_empty(); 11 // 返回“雙向鏈表的大小” 12 extern int dlink_size(); 13 14 // 獲取“雙向鏈表中第index位置的元素的值”。成功,返回節點值;否則,返回-1。 15 extern int dlink_get(int index); 16 // 獲取“雙向鏈表中第1個元素的值”。成功,返回節點值;否則,返回-1。 17 extern int dlink_get_first(); 18 // 獲取“雙向鏈表中最后1個元素的值”。成功,返回節點值;否則,返回-1。 19 extern int dlink_get_last(); 20 21 // 將“value”插入到index位置。成功,返回0;否則,返回-1。 22 extern int dlink_insert(int index, int value); 23 // 將“value”插入到表頭位置。成功,返回0;否則,返回-1。 24 extern int dlink_insert_first(int value); 25 // 將“value”插入到末尾位置。成功,返回0;否則,返回-1。 26 extern int dlink_append_last(int value); 27 28 // 刪除“雙向鏈表中index位置的節點”。成功,返回0;否則,返回-1 29 extern int dlink_delete(int index); 30 // 刪除第一個節點。成功,返回0;否則,返回-1 31 extern int dlink_delete_first(); 32 // 刪除組后一個節點。成功,返回0;否則,返回-1 33 extern int dlink_delete_last(); 34 35 // 打印“雙向鏈表” 36 extern void print_dlink(); 37 38 #endif
雙向鏈表的實現文件(double_link.c)

1 #include <stdio.h> 2 #include <malloc.h> 3 4 /** 5 * C 語言: 雙向鏈表,只能存儲int數據。 6 * 7 * @author skywang 8 * @date 2013/11/07 9 */ 10 11 // 雙向鏈表節點 12 typedef struct tag_node 13 { 14 struct tag_node *prev; 15 struct tag_node *next; 16 int value; 17 }node; 18 19 // 表頭。注意,表頭不存放元素值!!! 20 static node *phead=NULL; 21 // 節點個數。 22 static int count=0; 23 24 // 新建“節點”。成功,返回節點指針;否則,返回NULL。 25 static node* create_node(int value) 26 { 27 node *pnode=NULL; 28 pnode = (node *)malloc(sizeof(node)); 29 if (!pnode) 30 { 31 printf("create node error!\n"); 32 return NULL; 33 } 34 // 默認的,pnode的前一節點和后一節點都指向它自身 35 pnode->prev = pnode->next = pnode; 36 // 節點的值為value 37 pnode->value = value; 38 39 return pnode; 40 } 41 42 // 新建“雙向鏈表”。成功,返回0;否則,返回-1。 43 int create_dlink() 44 { 45 // 創建表頭 46 phead = create_node(-1); 47 if (!phead) 48 return -1; 49 50 // 設置“節點個數”為0 51 count = 0; 52 53 return 0; 54 } 55 56 // “雙向鏈表是否為空” 57 int dlink_is_empty() 58 { 59 return count == 0; 60 } 61 62 // 返回“雙向鏈表的大小” 63 int dlink_size() { 64 return count; 65 } 66 67 // 獲取“雙向鏈表中第index位置的節點” 68 static node* get_node(int index) 69 { 70 if (index<0 || index>=count) 71 { 72 printf("%s failed! the index in out of bound!\n", __func__); 73 return NULL; 74 } 75 76 // 正向查找 77 if (index <= (count/2)) 78 { 79 int i=0; 80 node *pnode=phead->next; 81 while ((i++) < index) 82 pnode = pnode->next; 83 84 return pnode; 85 } 86 87 // 反向查找 88 int j=0; 89 int rindex = count - index - 1; 90 node *rnode=phead->prev; 91 while ((j++) < rindex) 92 rnode = rnode->prev; 93 94 return rnode; 95 } 96 97 // 獲取“第一個節點” 98 static node* get_first_node() 99 { 100 return get_node(0); 101 } 102 103 // 獲取“最后一個節點” 104 static node* get_last_node() 105 { 106 return get_node(count-1); 107 } 108 109 // 獲取“雙向鏈表中第index位置的元素的值”。成功,返回節點值;否則,返回-1。 110 int dlink_get(int index) 111 { 112 node *pindex=get_node(index); 113 if (!pindex) 114 { 115 printf("%s failed!\n", __func__); 116 return -1; 117 } 118 119 return pindex->value; 120 121 } 122 123 // 獲取“雙向鏈表中第1個元素的值” 124 int dlink_get_first() 125 { 126 return dlink_get(0); 127 } 128 129 // 獲取“雙向鏈表中最后1個元素的值” 130 int dlink_get_last() 131 { 132 return dlink_get(count-1); 133 } 134 135 // 將“value”插入到index位置。成功,返回0;否則,返回-1。 136 int dlink_insert(int index, int value) 137 { 138 // 插入表頭 139 if (index==0) 140 return dlink_insert_first(value); 141 142 // 獲取要插入的位置對應的節點 143 node *pindex=get_node(index); 144 if (!pindex) 145 return -1; 146 147 // 創建“節點” 148 node *pnode=create_node(value); 149 if (!pnode) 150 return -1; 151 152 pnode->prev = pindex->prev; 153 pnode->next = pindex; 154 pindex->prev->next = pnode; 155 pindex->prev = pnode; 156 // 節點個數+1 157 count++; 158 159 return 0; 160 } 161 162 // 將“value”插入到表頭位置 163 int dlink_insert_first(int value) 164 { 165 node *pnode=create_node(value); 166 if (!pnode) 167 return -1; 168 169 pnode->prev = phead; 170 pnode->next = phead->next; 171 phead->next->prev = pnode; 172 phead->next = pnode; 173 count++; 174 return 0; 175 } 176 177 // 將“value”插入到末尾位置 178 int dlink_append_last(int value) 179 { 180 node *pnode=create_node(value); 181 if (!pnode) 182 return -1; 183 184 pnode->next = phead; 185 pnode->prev = phead->prev; 186 phead->prev->next = pnode; 187 phead->prev = pnode; 188 count++; 189 return 0; 190 } 191 192 // 刪除“雙向鏈表中index位置的節點”。成功,返回0;否則,返回-1。 193 int dlink_delete(int index) 194 { 195 node *pindex=get_node(index); 196 if (!pindex) 197 { 198 printf("%s failed! the index in out of bound!\n", __func__); 199 return -1; 200 } 201 202 pindex->next->prev = pindex->prev; 203 pindex->prev->next = pindex->next; 204 free(pindex); 205 count--; 206 207 return 0; 208 } 209 210 // 刪除第一個節點 211 int dlink_delete_first() 212 { 213 return dlink_delete(0); 214 } 215 216 // 刪除組后一個節點 217 int dlink_delete_last() 218 { 219 return dlink_delete(count-1); 220 } 221 222 // 撤銷“雙向鏈表”。成功,返回0;否則,返回-1。 223 int destroy_dlink() 224 { 225 if (!phead) 226 { 227 printf("%s failed! dlink is null!\n", __func__); 228 return -1; 229 } 230 231 node *pnode=phead->next; 232 node *ptmp=NULL; 233 while(pnode != phead) 234 { 235 ptmp = pnode; 236 pnode = pnode->next; 237 free(ptmp); 238 } 239 240 free(phead); 241 phead = NULL; 242 count = 0; 243 244 return 0; 245 } 246 247 // 打印“雙向鏈表” 248 void print_dlink() 249 { 250 if (count==0 || (!phead)) 251 { 252 printf("%s dlink is empty!\n", __func__); 253 return ; 254 } 255 256 printf("%s dlink size()=%d\n", __func__, count); 257 node *pnode=phead->next; 258 while(pnode != phead) 259 { 260 printf("%d\n", pnode->value); 261 pnode = pnode->next; 262 } 263 }
雙向鏈表的測試程序(dlink_queue.c)

1 #include <stdio.h> 2 #include "double_link.h" 3 4 /** 5 * C 語言: 雙向鏈表實現“隊列”,只能存儲int數據。 6 * 7 * @author skywang 8 * @date 2013/11/07 9 */ 10 11 // 創建隊列 12 int create_dlink_queue() 13 { 14 return create_dlink(); 15 } 16 17 // 銷毀隊列 18 int destroy_dlink_queue() 19 { 20 return destroy_dlink(); 21 } 22 23 // 將val添加到隊列的末尾 24 int add(int val) 25 { 26 return dlink_append_last(val); 27 } 28 29 // 返回“隊列開頭元素” 30 int front() 31 { 32 return dlink_get_first(); 33 } 34 35 // 返回並刪除“隊列開頭元素” 36 int pop() 37 { 38 int ret = dlink_get_first(); 39 dlink_delete_first(); 40 return ret; 41 } 42 43 // 返回“隊列”的大小 44 int size() 45 { 46 return dlink_size(); 47 } 48 49 // 返回“隊列”是否為空 50 int is_empty() 51 { 52 return dlink_is_empty(); 53 } 54 55 void main() 56 { 57 int tmp=0; 58 59 // 創建“隊列” 60 create_dlink_queue(); 61 62 // 將10, 20, 30 依次隊列中 63 add(10); 64 add(20); 65 add(30); 66 67 // 將“隊列開頭的元素”賦值給tmp,並刪除“該元素” 68 tmp = pop(); 69 printf("tmp=%d\n", tmp); 70 71 // 只將“隊列開頭的元素”賦值給tmp,不刪除該元素. 72 tmp = front(); 73 printf("tmp=%d\n", tmp); 74 75 add(40); 76 77 printf("is_empty()=%d\n", is_empty()); 78 printf("size()=%d\n", size()); 79 while (!is_empty()) 80 { 81 printf("%d\n", pop()); 82 } 83 84 // 銷毀隊列 85 destroy_dlink_queue(); 86 }
代碼說明:"運行結果" 以及 "主函數main的邏輯"都和前兩個示例的一樣。不同的是,該示例中的隊列是通過雙向鏈表實現的。
4. C語言實現四:雙向鏈表實現的隊列,能存儲任意類型的數據
實現代碼
雙向鏈表的頭文件(double_link.h)

1 #ifndef _DOUBLE_LINK_H 2 #define _DOUBLE_LINK_H 3 4 // 新建“雙向鏈表”。成功,返回表頭;否則,返回NULL 5 extern int create_dlink(); 6 // 撤銷“雙向鏈表”。成功,返回0;否則,返回-1 7 extern int destroy_dlink(); 8 9 // “雙向鏈表是否為空”。為空的話返回1;否則,返回0。 10 extern int dlink_is_empty(); 11 // 返回“雙向鏈表的大小” 12 extern int dlink_size(); 13 14 // 獲取“雙向鏈表中第index位置的元素”。成功,返回節點指針;否則,返回NULL。 15 extern void* dlink_get(int index); 16 // 獲取“雙向鏈表中第1個元素”。成功,返回節點指針;否則,返回NULL。 17 extern void* dlink_get_first(); 18 // 獲取“雙向鏈表中最后1個元素”。成功,返回節點指針;否則,返回NULL。 19 extern void* dlink_get_last(); 20 21 // 將“value”插入到index位置。成功,返回0;否則,返回-1。 22 extern int dlink_insert(int index, void *pval); 23 // 將“value”插入到表頭位置。成功,返回0;否則,返回-1。 24 extern int dlink_insert_first(void *pval); 25 // 將“value”插入到末尾位置。成功,返回0;否則,返回-1。 26 extern int dlink_append_last(void *pval); 27 28 // 刪除“雙向鏈表中index位置的節點”。成功,返回0;否則,返回-1 29 extern int dlink_delete(int index); 30 // 刪除第一個節點。成功,返回0;否則,返回-1 31 extern int dlink_delete_first(); 32 // 刪除組后一個節點。成功,返回0;否則,返回-1 33 extern int dlink_delete_last(); 34 35 #endif
雙向鏈表的實現文件(double_link.c)

1 #include <stdio.h> 2 #include <malloc.h> 3 4 /** 5 * C 語言: 雙向鏈表,能存儲任意數據。 6 * 7 * @author skywang 8 * @date 2013/11/07 9 */ 10 11 // 雙向鏈表節點 12 typedef struct tag_node 13 { 14 struct tag_node *prev; 15 struct tag_node *next; 16 void* p; 17 }node; 18 19 // 表頭。注意,表頭不存放元素值!!! 20 static node *phead=NULL; 21 // 節點個數。 22 static int count=0; 23 24 // 新建“節點”。成功,返回節點指針;否則,返回NULL。 25 static node* create_node(void *pval) 26 { 27 node *pnode=NULL; 28 pnode = (node *)malloc(sizeof(node)); 29 if (!pnode) 30 { 31 printf("create node error!\n"); 32 return NULL; 33 } 34 // 默認的,pnode的前一節點和后一節點都指向它自身 35 pnode->prev = pnode->next = pnode; 36 // 節點的值為pval 37 pnode->p = pval; 38 39 return pnode; 40 } 41 42 // 新建“雙向鏈表”。成功,返回0;否則,返回-1。 43 int create_dlink() 44 { 45 // 創建表頭 46 phead = create_node(NULL); 47 if (!phead) 48 return -1; 49 50 // 設置“節點個數”為0 51 count = 0; 52 53 return 0; 54 } 55 56 // “雙向鏈表是否為空” 57 int dlink_is_empty() 58 { 59 return count == 0; 60 } 61 62 // 返回“雙向鏈表的大小” 63 int dlink_size() { 64 return count; 65 } 66 67 // 獲取“雙向鏈表中第index位置的節點” 68 static node* get_node(int index) 69 { 70 if (index<0 || index>=count) 71 { 72 printf("%s failed! index out of bound!\n", __func__); 73 return NULL; 74 } 75 76 // 正向查找 77 if (index <= (count/2)) 78 { 79 int i=0; 80 node *pnode=phead->next; 81 while ((i++) < index) 82 pnode = pnode->next; 83 84 return pnode; 85 } 86 87 // 反向查找 88 int j=0; 89 int rindex = count - index - 1; 90 node *rnode=phead->prev; 91 while ((j++) < rindex) 92 rnode = rnode->prev; 93 94 return rnode; 95 } 96 97 // 獲取“第一個節點” 98 static node* get_first_node() 99 { 100 return get_node(0); 101 } 102 103 // 獲取“最后一個節點” 104 static node* get_last_node() 105 { 106 return get_node(count-1); 107 } 108 109 // 獲取“雙向鏈表中第index位置的元素”。成功,返回節點值;否則,返回-1。 110 void* dlink_get(int index) 111 { 112 node *pindex=get_node(index); 113 if (!pindex) 114 { 115 printf("%s failed!\n", __func__); 116 return NULL; 117 } 118 119 return pindex->p; 120 121 } 122 123 // 獲取“雙向鏈表中第1個元素的值” 124 void* dlink_get_first() 125 { 126 return dlink_get(0); 127 } 128 129 // 獲取“雙向鏈表中最后1個元素的值” 130 void* dlink_get_last() 131 { 132 return dlink_get(count-1); 133 } 134 135 // 將“pval”插入到index位置。成功,返回0;否則,返回-1。 136 int dlink_insert(int index, void* pval) 137 { 138 // 插入表頭 139 if (index==0) 140 return dlink_insert_first(pval); 141 142 // 獲取要插入的位置對應的節點 143 node *pindex=get_node(index); 144 if (!pindex) 145 return -1; 146 147 // 創建“節點” 148 node *pnode=create_node(pval); 149 if (!pnode) 150 return -1; 151 152 pnode->prev = pindex->prev; 153 pnode->next = pindex; 154 pindex->prev->next = pnode; 155 pindex->prev = pnode; 156 // 節點個數+1 157 count++; 158 159 return 0; 160 } 161 162 // 將“pval”插入到表頭位置 163 int dlink_insert_first(void *pval) 164 { 165 node *pnode=create_node(pval); 166 if (!pnode) 167 return -1; 168 169 pnode->prev = phead; 170 pnode->next = phead->next; 171 phead->next->prev = pnode; 172 phead->next = pnode; 173 count++; 174 return 0; 175 } 176 177 // 將“pval”插入到末尾位置 178 int dlink_append_last(void *pval) 179 { 180 node *pnode=create_node(pval); 181 if (!pnode) 182 return -1; 183 184 pnode->next = phead; 185 pnode->prev = phead->prev; 186 phead->prev->next = pnode; 187 phead->prev = pnode; 188 count++; 189 return 0; 190 } 191 192 // 刪除“雙向鏈表中index位置的節點”。成功,返回0;否則,返回-1。 193 int dlink_delete(int index) 194 { 195 node *pindex=get_node(index); 196 if (!pindex) 197 { 198 printf("%s failed! the index in out of bound!\n", __func__); 199 return -1; 200 } 201 202 pindex->next->prev = pindex->prev; 203 pindex->prev->next = pindex->next; 204 free(pindex); 205 count--; 206 207 return 0; 208 } 209 210 // 刪除第一個節點 211 int dlink_delete_first() 212 { 213 return dlink_delete(0); 214 } 215 216 // 刪除組后一個節點 217 int dlink_delete_last() 218 { 219 return dlink_delete(count-1); 220 } 221 222 // 撤銷“雙向鏈表”。成功,返回0;否則,返回-1。 223 int destroy_dlink() 224 { 225 if (!phead) 226 { 227 printf("%s failed! dlink is null!\n", __func__); 228 return -1; 229 } 230 231 node *pnode=phead->next; 232 node *ptmp=NULL; 233 while(pnode != phead) 234 { 235 ptmp = pnode; 236 pnode = pnode->next; 237 free(ptmp); 238 } 239 240 free(phead); 241 phead = NULL; 242 count = 0; 243 244 return 0; 245 }
雙向鏈表的測試程序(dlink_queue.c)

1 #include <stdio.h> 2 #include "double_link.h" 3 4 /** 5 * C 語言: 雙向鏈表實現“隊列”,能存儲任意數據。 6 * 7 * @author skywang 8 * @date 2013/11/07 9 */ 10 11 // 創建隊列 12 int create_dlink_queue() 13 { 14 return create_dlink(); 15 } 16 17 // 銷毀隊列 18 int destroy_dlink_queue() 19 { 20 return destroy_dlink(); 21 } 22 23 // 將p添加到隊列的末尾 24 int add(void *p) 25 { 26 return dlink_append_last(p); 27 } 28 29 // 返回“隊列開頭元素” 30 void* front() 31 { 32 return dlink_get_first(); 33 } 34 35 // 返回“隊列開頭的元素”,並刪除“該元素” 36 void* pop() 37 { 38 void *p = dlink_get_first(); 39 dlink_delete_first(); 40 return p; 41 } 42 43 // 返回“隊列”的大小 44 int size() 45 { 46 return dlink_size(); 47 } 48 49 // 返回“隊列”是否為空 50 int is_empty() 51 { 52 return dlink_is_empty(); 53 } 54 55 56 typedef struct tag_stu 57 { 58 int id; 59 char name[20]; 60 }stu; 61 62 static stu arr_stu[] = 63 { 64 {10, "sky"}, 65 {20, "jody"}, 66 {30, "vic"}, 67 {40, "dan"}, 68 }; 69 #define ARR_STU_SIZE ( (sizeof(arr_stu)) / (sizeof(arr_stu[0])) ) 70 71 static void print_stu(stu *p) 72 { 73 if (!p) 74 return ; 75 76 printf("id=%d, name=%s\n", p->id, p->name); 77 } 78 79 void main() 80 { 81 stu *pval=NULL; 82 83 // 創建“隊列” 84 create_dlink_queue(); 85 86 // 將10, 20, 30 依次推入隊列中 87 int i=0; 88 for (i=0; i<ARR_STU_SIZE-1; i++) 89 { 90 add(&arr_stu[i]); 91 } 92 93 // 將“隊列開頭的元素”賦值給tmp,並刪除“該元素” 94 pval = (stu*)pop(); 95 print_stu(pval) ; 96 97 // 只將“隊列開頭的元素”賦值給tmp,不刪除該元素. 98 pval = front(); 99 print_stu(pval) ; 100 101 add(&arr_stu[ARR_STU_SIZE-1]); 102 103 printf("is_empty()=%d\n", is_empty()); 104 printf("size()=%d\n", size()); 105 // 打印隊列中的所有元素 106 while (!is_empty()) 107 { 108 pval = pop(); 109 print_stu(pval) ; 110 } 111 112 // 銷毀隊列 113 destroy_dlink_queue(); 114 }
運行結果:
id=10, name=sky id=20, name=jody is_empty()=0 size()=3 id=20, name=jody id=30, name=vic id=40, name=dan
結果說明:該示例中的隊列是通過雙向鏈表實現的,並且能存儲任意類型的數據。
隊列的C++實現
C++的STL中本身就包含了list類,基本上該list類就能滿足我們的需求,所以很少需要我們自己來實現。本部分介紹2種C++實現。
1. C++實現一:數組實現的隊列,能存儲任意類型的數據。
2. C++實現二:C++的 STL 中自帶的"隊列"(list)的示例。
1. C++實現一:數組實現的隊列,能存儲任意類型的數據
實現代碼
隊列的實現文件(ArrayQueue.h)

1 #ifndef ARRAY_QUEUE_HXX 2 #define ARRAY_QUEUE_HXX 3 4 #include <iostream> 5 using namespace std; 6 7 template<class T> class ArrayQueue{ 8 public: 9 ArrayQueue(); 10 ~ArrayQueue(); 11 12 void add(T t); 13 T front(); 14 T pop(); 15 int size(); 16 int is_empty(); 17 18 private: 19 T *arr; 20 int count; 21 }; 22 23 // 創建“隊列”,默認大小是12 24 template<class T> 25 ArrayQueue<T>::ArrayQueue() 26 { 27 arr = new T[12]; 28 if (!arr) 29 { 30 cout<<"arr malloc error!"<<endl; 31 } 32 } 33 34 // 銷毀“隊列” 35 template<class T> 36 ArrayQueue<T>::~ArrayQueue() 37 { 38 if (arr) 39 { 40 delete[] arr; 41 arr = NULL; 42 } 43 } 44 45 // 將val添加到隊列的末尾 46 template<class T> 47 void ArrayQueue<T>::add(T t) 48 { 49 arr[count++] = t; 50 } 51 52 53 // 返回“隊列開頭元素” 54 template<class T> 55 T ArrayQueue<T>::front() 56 { 57 return arr[0]; 58 } 59 60 // 返回並刪除“隊列末尾的元素” 61 template<class T> 62 T ArrayQueue<T>::pop() 63 { 64 int i = 0;; 65 T ret = arr[0]; 66 67 count--; 68 while (i++<count) 69 arr[i-1] = arr[i]; 70 71 return ret; 72 } 73 74 // 返回“隊列”的大小 75 template<class T> 76 int ArrayQueue<T>::size() 77 { 78 return count; 79 } 80 81 // 返回“隊列”是否為空 82 template<class T> 83 int ArrayQueue<T>::is_empty() 84 { 85 return count==0; 86 } 87 88 89 #endif
隊列的測試程序(Main.cpp)

1 #include <iostream> 2 #include "ArrayQueue.h" 3 using namespace std; 4 5 /** 6 * C++ : 數組實現“隊列”,能存儲任意數據。 7 * 8 * @author skywang 9 * @date 2013/11/07 10 */ 11 int main() 12 { 13 int tmp=0; 14 ArrayQueue<int> *astack = new ArrayQueue<int>(); 15 16 // 將10, 20, 30 依次推入隊列中 17 astack->add(10); 18 astack->add(20); 19 astack->add(30); 20 21 // 將“隊列開頭元素”賦值給tmp,並刪除“該元素” 22 tmp = astack->pop(); 23 cout<<"tmp="<<tmp<<endl; 24 25 // 只將“隊列開頭的元素”賦值給tmp,不刪除該元素. 26 tmp = astack->front(); 27 cout<<"tmp="<<tmp<<endl; 28 29 astack->add(40); 30 31 cout<<"is_empty()="<<astack->is_empty()<<endl; 32 cout<<"size()="<<astack->size()<<endl; 33 while (!astack->is_empty()) 34 { 35 tmp = astack->pop(); 36 cout<<tmp<<endl; 37 } 38 39 return 0; 40 }
運行結果:
tmp=10 tmp=20 is_empty()=0 size()=3 20 30 40
結果說明:關於"隊列的聲明和實現都在頭文件中"的原因,是因為隊列的實現利用了C++模板,而"C++編譯器不能支持對模板的分離式編譯"。
2. C++實現二:C++的 STL 中自帶的"隊列"(list)的示例
實現代碼(StlQueue.cpp)

1 #include <iostream> 2 #include <queue> 3 using namespace std; 4 5 /** 6 * C++ : STL中的隊列(queue)的演示程序。 7 * 8 * @author skywang 9 * @date 2013/11/07 10 */ 11 int main () 12 { 13 int tmp=0; 14 queue<int> iqueue; 15 16 // 將10, 20, 30 依次加入隊列的末尾 17 iqueue.push(10); 18 iqueue.push(20); 19 iqueue.push(30); 20 21 // 刪除隊列開頭的元素 22 iqueue.pop(); 23 24 // 將“隊列開頭的元素”賦值給tmp,不刪除該元素. 25 tmp = iqueue.front(); 26 cout<<"tmp="<<tmp<<endl; 27 28 // 將40加入到隊列的末尾 29 iqueue.push(40); 30 31 cout << "empty()=" << iqueue.empty() <<endl; 32 cout << "size()=" << iqueue.size() <<endl; 33 while (!iqueue.empty()) 34 { 35 tmp = iqueue.front(); 36 cout<<tmp<<endl; 37 iqueue.pop(); 38 } 39 40 return 0; 41 }
運行結果:
tmp=20 empty()=0 size()=3 20 30 40
隊列的Java實現
和C++一樣,JDK包Queue中的也提供了"隊列"的實現。JDK中的Queue接口就是"隊列",它的實現類也都是隊列,用的最多的是LinkedList。本部分介紹給出2種Java實現
1. Java實現一:數組實現的隊列,能存儲任意類型的數據。
2. Java實現二:Java的 Collection集合 中自帶的"隊列"(LinkedList)的示例。
1. Java實現一:數組實現的隊列,能存儲任意類型的數據
實現代碼(ArrayQueue.java)

1 /** 2 * Java : 數組實現“隊列”,只能存儲int數據。 3 * 4 * @author skywang 5 * @date 2013/11/07 6 */ 7 public class ArrayQueue { 8 9 private int[] mArray; 10 private int mCount; 11 12 public ArrayQueue(int sz) { 13 mArray = new int[sz]; 14 mCount = 0; 15 } 16 17 // 將val添加到隊列的末尾 18 public void add(int val) { 19 mArray[mCount++] = val; 20 } 21 22 // 返回“隊列開頭元素” 23 public int front() { 24 return mArray[0]; 25 } 26 27 // 返回“棧頂元素值”,並刪除“棧頂元素” 28 public int pop() { 29 int ret = mArray[0]; 30 mCount--; 31 for (int i=1; i<=mCount; i++) 32 mArray[i-1] = mArray[i]; 33 return ret; 34 } 35 36 // 返回“棧”的大小 37 public int size() { 38 return mCount; 39 } 40 41 // 返回“棧”是否為空 42 public boolean isEmpty() { 43 return size()==0; 44 } 45 46 public static void main(String[] args) { 47 int tmp=0; 48 ArrayQueue astack = new ArrayQueue(12); 49 50 // 將10, 20, 30 依次推入棧中 51 astack.add(10); 52 astack.add(20); 53 astack.add(30); 54 55 // 將“棧頂元素”賦值給tmp,並刪除“棧頂元素” 56 tmp = astack.pop(); 57 System.out.printf("tmp=%d\n", tmp); 58 59 // 只將“棧頂”賦值給tmp,不刪除該元素. 60 tmp = astack.front(); 61 System.out.printf("tmp=%d\n", tmp); 62 63 astack.add(40); 64 65 System.out.printf("isEmpty()=%b\n", astack.isEmpty()); 66 System.out.printf("size()=%d\n", astack.size()); 67 while (!astack.isEmpty()) { 68 System.out.printf("size()=%d\n", astack.pop()); 69 } 70 } 71 }
運行結果:
tmp=10 tmp=20 isEmpty()=false size()=3 size()=20 size()=30 size()=40
結果說明:ArrayQueue是通過數組實現的隊列,而且ArrayQueue中使用到了泛型,因此它支持任意類型的數據。
2. Java實現二:Java的 Collection集合 中自帶的"隊列"(LinkedList)的示例
實現代碼(QueueTest.java)

1 import java.util.Stack; 2 3 /** 4 * 用“棧”實現隊列 5 * 6 * @author skywang 7 */ 8 public class StackList<T> { 9 10 // 向隊列添加數據時:(01) 將“已有的全部數據”都移到mIn中。 (02) 將“新添加的數據”添加到mIn中。 11 private Stack<T> mIn = null; 12 // 從隊列獲取元素時:(01) 將“已有的全部數據”都移到mOut中。(02) 返回並刪除mOut棧頂元素。 13 private Stack<T> mOut = null; 14 // 統計計數 15 private int mCount = 0; 16 17 public StackList() { 18 mIn = new Stack<T>(); 19 mOut = new Stack<T>(); 20 mCount = 0; 21 } 22 23 private void add(T t) { 24 // 將“已有的全部數據”都移到mIn中 25 while (!mOut.empty()) 26 mIn.push(mOut.pop()); 27 28 // 將“新添加的數據”添加到mIn中 29 mIn.push(t); 30 // 統計數+1 31 mCount++; 32 } 33 34 private T get() { 35 // 將“已有的全部數據”都移到mOut中 36 while (!mIn.empty()) 37 mOut.push(mIn.pop()); 38 // 統計數-1 39 mCount--; 40 41 // 返回並刪除mOut棧頂元素 42 return mOut.pop(); 43 } 44 45 private int size() { 46 return mCount; 47 } 48 private boolean isEmpty() { 49 return mCount==0; 50 } 51 52 public static void main(String[] args) { 53 StackList slist = new StackList(); 54 55 // 將10, 20, 30 依次推入棧中 56 slist.add(10); 57 slist.add(20); 58 slist.add(30); 59 60 System.out.printf("isEmpty()=%b\n", slist.isEmpty()); 61 System.out.printf("size()=%d\n", slist.size()); 62 while(!slist.isEmpty()) { 63 System.out.printf("%d\n", slist.get()); 64 } 65 } 66 }
運行結果:
tmp=10 tmp=20 isEmpty()=false size()=3 tmp=20 tmp=30 tmp=40