实现了简单的栈和队列之后,我们可以考虑玩点花样:怎么用两个栈实现一个队列的功能
用两个栈实现队列说起来也不是很困难,我们根据栈的特性:后进先出,也就是先进后出,相当于把数据倒过来了,这样我们用两个栈颠倒了两次,也就是实现了队列的功能:先进先出。
对这个用两个栈S1和S2形成的队列进行操作时,我们该怎么样操作呢?
数据入队列:数据录入相当简单,直接把数据录入栈S1即可。
数据出队列:数据出队相对麻烦,我们把栈S1的数据依次录入栈S2,弹出栈S1,这样S2的内容就符合出队要求了。
只需要对S2进行出栈操作就行。
思路:入栈进S1,出栈由S2完成,如果S2无数据,把S1的数据压入S2。
工具:VS2013
语言:C
代码如下:
头文件QueueByTwoStack.h1
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#pragma once
#include <stdio.h>
#include <malloc.h>
#include <assert.h>
typedef int DataType;
typedef struct Stack
{
DataType* data;
int top; // 栈顶
int capacity; // 容量
}Stack;
// 两个栈实现一个队列
typedef struct QueueByTwoStack
{
Stack s1;
Stack s2;
}QueueByTwoStack;
void QueueInit(QueueByTwoStack* pq);
void QueueDestory(QueueByTwoStack* pq);
void QueuePush(QueueByTwoStack* pq, DataType x);
void QueuePop(QueueByTwoStack* pq);
DataType QueueFront(QueueByTwoStack* pq);
int QueueEmpty(QueueByTwoStack* pq);
int QueueSize(QueueByTwoStack* pq);
void TestQueue();
void StackInit(Stack* ps);
void StackDestory(Stack* ps);
void StackPush(Stack* ps, DataType x);
void StackPop(Stack* ps);
DataType StackTop(Stack* ps);
int StackEmpty(Stack* ps);
int StackSize(Stack* ps);
源文件Stack.c1
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#include "QueueByTwoStack.h"
void StackInit(Stack* ps)
{
assert(ps);
ps->data = (DataType*)malloc(sizeof(Stack)* 3);
ps->capacity = 3;
ps->top = 0;
}
void StackDestory(Stack* ps)
{
assert(ps);
if (ps->data)
free(ps->data);
ps->capacity = 0;
ps->top = 0;
}
void StackPush(Stack* ps, DataType x)
{
assert(ps);
if (ps->top == ps->capacity)
{
ps->data = (DataType*)realloc(ps->data, sizeof(Stack)*(ps->capacity * 2));
if (ps->data)
ps->capacity *= 2;
else perror("capacity realloc");
}
*(ps->data + ps->top++) = x;
}
void StackPop(Stack* ps)
{
assert(ps&&ps->data);
if (ps->top)
ps->top--;
}
DataType StackTop(Stack* ps)
{
assert(ps&&ps->data&&ps->top);
return *(ps->data + ps->top - 1);
}
int StackEmpty(Stack* ps)
{
assert(ps);
return ps->top != 0;
}
int StackSize(Stack* ps)
{
assert(ps&&ps->data);
return ps->top;
}
QueueByTwoStack.c1
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#include"QueueByTwoStack.h"
void QueueInit(QueueByTwoStack* pq)
{
assert(pq);
StackInit(&pq->s1);
StackInit(&pq->s2);
}
void QueueDestory(QueueByTwoStack* pq)
{
assert(pq);
StackDestory(&pq->s1);
StackDestory(&pq->s2);
}
void QueuePush(QueueByTwoStack* pq, DataType x)
{
assert(pq);
StackPush(&pq->s1, x);
}
void QueuePop(QueueByTwoStack* pq)
{
assert(pq);
if (StackEmpty(&pq->s2))
StackPop((&pq->s2));
else if (StackEmpty(&pq->s1))
{
while (StackEmpty(&pq->s1))
{
StackPush(&pq->s2, StackTop(&pq->s1));
StackPop(&pq->s1);
}
}
}
DataType QueueFront(QueueByTwoStack* pq)
{
assert(pq);
if (StackEmpty(&pq->s2) == 0)
{
while (StackEmpty(&pq->s1))
{
StackPush(&pq->s2, StackTop(&pq->s1));
StackPop(&pq->s1);
}
}
return StackTop(&pq->s2);
}
int QueueEmpty(QueueByTwoStack* pq)
{
assert(pq);
return StackEmpty(&pq->s1) || StackEmpty(&pq->s1);
}
int QueueSize(QueueByTwoStack* pq)
{
assert(pq);
return StackSize(&pq->s1) + StackSize(&pq->s2);
}
void TestQueue()
{
QueueByTwoStack q;
int i;
QueueInit(&q);
QueuePush(&q, 1);
QueuePush(&q, 2);
QueuePush(&q, 3);
QueuePush(&q, 4);
QueuePush(&q, 5);
QueuePush(&q, 6);
printf("Size:%d\n", QueueSize(&q));
printf("empty:%d\n", QueueEmpty(&q));
for (i = 0; i < 6; i++)
{
printf("%d ", QueueFront(&q));
QueuePop(&q);
}
printf("\nSize:%d", QueueSize(&q));
printf("\nempty:%d", QueueEmpty(&q));
QueueDestory(&q);
}
Test.c1
2
3
4
5
6
7
8#include"QueueByTwoStack.h"
#include<windows.h>
int main()
{
TestQueue();
system("pause");
return 0;
}