两个队列实现一个栈

题目:用两个队列模拟一个栈,即用两个队列的出队和入队操作,来实现栈的出栈和入栈操作。

思路:稍微画下草图,便不难想出该题的解决方法,思路如下:

假设有两个队列Q1和Q2,当二者都为空时,入栈操作可以用入队操作来模拟,可以随便选一个空队列,假设选Q1进行入栈操作,现在假设a,b,c依次入栈了(即依次进入队列Q1),这时如果想模拟出栈操作,则需要将c出栈,因为在栈顶,这时候可以考虑用空队列Q2,将a,b依次从Q1中出队,而后进入队列Q2,将Q1的最后一个元素c出队即可,此时Q1变为了空队列,Q2中有两个元素,队头元素为a,队尾元素为b,接下来如果再执行入栈操作,则需要将元素进入到Q1和Q2中的非空队列,即进入Q2队列,出栈的话,就跟前面的一样,将Q2除最后一个元素外全部出队,并依次进入队列Q1,再将Q2的最后一个元素出队即可。

实现代码如下:

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/*
用两个队列模拟入栈操作
*/
void push(PQUEUE pS1,PQUEUE pS2, int val)
{
     if (is_empty(pS2))
         en_queue(pS1, val);
     else
         en_queue(pS2, val);
}
 
/*
用两个队列模拟出栈操作
*/
bool pop(PQUEUE pS1,PQUEUE pS2, int *pData)
{
     if (is_empty(pS1) && is_empty(pS2))
         return false ;
 
     int DelData;
     if (!is_empty(pS2))
     {
         int len = length(pS2);
         while (len-- > 1 )
         {
             de_queue(pS2,&DelData);
             en_queue(pS1,DelData);
         }
         //将队列的最后一个元素出队,作为出栈元素
         de_queue(pS2,pData);
         return true ;
     }
     if (!is_empty(pS1))
     {
         int len = length(pS1);
         while (len-- > 1 )
         {
             de_queue(pS1,&DelData);
             en_queue(pS2,DelData);
         }
         //将队列的最后一个元素出队,作为出栈元素
         de_queue(pS1,pData);
         return true ;
     }
}

完整的代码(用的以前写的链式队列)如下:

 

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
/*******************************************************************
题目:用两个队列模拟一个栈
*******************************************************************/
 
#include<stdio.h>
#include<stdlib.h>
 
typedef struct Node
{
     int data;
     struct Node *pNext;
}NODE,*PNODE;
 
typedef struct Queue
{
     PNODE front;  //队头指针
     PNODE rear;   //队尾指针
}QUEUE,*PQUEUE;
 
PQUEUE create_queue();
bool is_empty(PQUEUE);
void en_queue(PQUEUE, int );
bool de_queue(PQUEUE, int *);
void destroy_queue(PQUEUE);
void traverse_queue(PQUEUE);
int length(PQUEUE);
void push(PQUEUE,PQUEUE, int );
bool pop(PQUEUE,PQUEUE, int *);
 
int main()
{
     int pData;         //用来保存出队的元素值
 
     //创建队列并进行入队测试
     PQUEUE pS1 = create_queue();
     PQUEUE pS2 = create_queue();
     push(pS1,pS2, 4 );
     push(pS1,pS2, 5 );
     printf(the length of pS1: %d
,length(pS1));
     printf(the length of pS2: %d
,length(pS2));
     if (pop(pS1,pS2,&pData))
         printf(%d is pop out
,pData);
     else
         printf(Stack is empty,can not pop
);
     printf(the length of pS1: %d
,length(pS1));
     printf(the length of pS2: %d
,length(pS2));
     push(pS1,pS2, 6 );
     printf(the length of pS1: %d
,length(pS1));
     printf(the length of pS2: %d
,length(pS2));
     push(pS1,pS2, 7 );
     printf(the length of pS1: %d
,length(pS1));
     printf(the length of pS2: %d
,length(pS2));
     if (pop(pS1,pS2,&pData))
         printf(%d is pop out
,pData);
     else
         printf(Stack is empty,can not pop
);
     printf(the length of pS1: %d
,length(pS1));
     printf(the length of pS2: %d
,length(pS2)); 
     if (pop(pS1,pS2,&pData))
         printf(%d is pop out
,pData);
     else
         printf(Stack is empty,can not pop
);
     printf(the length of pS1: %d
,length(pS1));
     printf(the length of pS2: %d
,length(pS2));
     if (pop(pS1,pS2,&pData))
         printf(%d is pop out
,pData);
     else
         printf(Stack is empty,can not pop
);
     printf(the length of pS1: %d
,length(pS1));
     printf(the length of pS2: %d
,length(pS2));
     if (pop(pS1,pS2,&pData))
         printf(%d is pop out
,pData);
     else
         printf(Stack is empty,can not pop
);
 
     return 0 ;
}
 
/*
创建一个空队列,队头指针和队尾指针都指向头结点,
头结点中不存放数据,只存放指针
*/
PQUEUE create_queue()
{
     PQUEUE pS = (PQUEUE)malloc(sizeof(Queue));
     pS->front = (PNODE)malloc(sizeof(NODE));
     if (!pS || !pS->front)
     {
         printf(pS or front malloc failed!!);
         exit(- 1 );
     }
     else
     {
         pS->rear = pS->front;
         pS->front->pNext = NULL;
     }
     return pS;
}
 
/*
判断队列是否为空
*/
bool is_empty(PQUEUE pS)
{
     if (pS->front == pS->rear)
         return true ;
     else
         return false ;
}
 
/*
进队函数,从队尾进队,队头指针保持不变
*/
void en_queue(PQUEUE pS, int e)
{
     PNODE pNew = (PNODE)malloc(sizeof(NODE));
     if (!pNew)
     {
         printf(pNew malloc failed);
         exit(- 1 );
     }
     else
     {
         pNew->data = e;
         pNew->pNext = NULL;
         pS->rear->pNext = pNew;
         pS->rear = pNew;
     }
     return ;
}
 
/*
出队函数,从队头出队,队尾指针保持不变,但当最后一个元素出队时,
需要对队尾指针重新赋值,使其指向头结点
*/
bool de_queue(PQUEUE pS, int *pData)
{
     if (is_empty(pS))
         return false ;
     else
     {
         PNODE p = pS->front->pNext;
         *pData = p->data;
         pS->front->pNext = p->pNext;
 
         //这里是队列头元素出队的特殊情况,一般情况下,删除队头元素时
         //仅需修改头结点中的指针,但当队列中最后一个元素被删除时,
         //队列尾指针也丢失了,因此需对队尾指针重新赋值(指向头结点)。
         if (pS->rear == p)        
             pS->rear = pS->front;
         free(p);
     }
     return true ;
}
 
/*
遍历队列,从对头向队尾依次输出队中的元素
*/
void traverse_queue(PQUEUE pS)
{
     if (is_empty(pS))
         printf(there is no data in the queue!
);
     else
     {  
         PNODE pCurrent = pS->front->pNext;
         printf(Now datas int the queue are:
);
         while (pCurrent)
         {
             printf(%d ,pCurrent->data);
             pCurrent = pCurrent->pNext;
         }
         printf(
);
     }
     return ;
}
 
/*
求队列的长度
*/
int length(PQUEUE pS)
{
     int count = 0 ;
     PNODE pCurrent = pS->front->pNext;
     while (pCurrent)
     {
         count++;
         pCurrent = pCurrent->pNext;
     }
     return count;
}
 
/*
销毁队列,头结点也被销毁,最后也将pS节点销毁,并将其指向为空,避免垂直指针的产生
*/
void destroy_queue(PQUEUE pS)
{
     if (is_empty(pS))
         return ;
     else
     {
         while (pS->front)
         {
             pS->rear = pS->front->pNext;
             free(pS->front);
             pS->front = pS->rear;
         }
     }
     free(pS);
     pS = 0 ;
     return ;
}
 
/*
用两个队列模拟入栈操作
*/
void push(PQUEUE pS1,PQUEUE pS2, int val)
{
     if (is_empty(pS2))
         en_queue(pS1, val);
     else
         en_queue(pS2, val);
}
 
/*
用两个队列模拟出栈操作
*/
bool pop(PQUEUE pS1,PQUEUE pS2, int *pData)
{
     if (is_empty(pS1) && is_empty(pS2))
         return false ;
 
     int DelData;
     if (!is_empty(pS2))
     {
         int len = length(pS2);
         while (len-- > 1 )
         {
             de_queue(pS2,&DelData);
             en_queue(pS1,DelData);
         }
         //将队列的最后一个元素出队,作为出栈元素
         de_queue(pS2,pData);
         return true ;
     }
     if (!is_empty(pS1))
     {
         int len = length(pS1);
         while (len-- > 1 )
         {
             de_queue(pS1,&DelData);
             en_queue(pS2,DelData);
         }
         //将队列的最后一个元素出队,作为出栈元素
         de_queue(pS1,pData);
         return true ;
     }
}</stdlib.h></stdio.h>

测试结果:

 

/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值