概要
本章和介绍"栈"时的流程一样,先对队列进行介绍,然后分别给出队列的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
来源:https://www.cnblogs.com/skywang12345/p/3562279.html



