Stack and Queue的模板案例

EaborH
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
#include <iostream>  
#include <cstdlib>
#include <cstdio>
using namespace std;

#define MaxSize 50
#define InitSize 100

typedef int ElemType;

// 栈
typedef struct {
ElemType data[MaxSize]; // 静态数组存放栈中元素
int top; // 栈顶指针
}SqStack;

// 初始化
void InitStack(SqStack &S) {
S.top=-1; // 初始栈顶指针(默认空栈为-1)
}
// 判断栈是否为空
bool StackEmpty(SqStack S) {
if (S.top==-1)
return true;
else
return false;
}
// 进栈操作
bool StackPush(SqStack &S, ElemType x) {
if (S.top == MaxSize-1) // 栈满
return false;
S.data[++S.top]=x; // 栈顶指针要先加 1 注意!!!!!
return true;
}
// 出栈操作
bool StackPop(SqStack &S, ElemType &x) {
if (S.top==-1) // 栈空
return false;
x=S.data[S.top--]; // 先出栈,栈顶指针再减 1 注意区别!!!!!
return true;
}
// 读取栈顶元素
bool StackGetTop(SqStack S, ElemType &x) {
if (S.top==-1)
return false;
x=S.data[S.top];
return true;
}

// 栈的链式存储
typedef struct LNode {
ElemType data;
struct LNode *next;
}LNode, *LiStack;

// 初始化
void InitLinkStack(LiStack &L) {
L=NULL;
}
// 入栈
bool LinkStackPush(LiStack &L, ElemType e) {
LNode *s=(LNode *)malloc(sizeof(LNode));
if (s==NULL)
return false;
s->next=L;
s->data=e;
L=s;
return true;
}
// 出栈
bool LinkStackPop(LiStack &L, ElemType &e) {
if (L==NULL)
return false;
LNode *q=L;
e=q->data;
L=q->next;
free(q);
return true;
}
// 获取栈顶元素
bool LinkStackGetTop(LiStack L, ElemType &e) {
if (L==NULL)
return false;
e=L->data;
return true;
}

// 队列
typedef struct {
ElemType data[MaxSize];
int front, rear;
}SqQueue;

// 初始化
void InitQueue(SqQueue &Q) {
Q.rear=Q.front=0; // 队头,队尾指向0
}
// 判断队列是否为空(非循环队列)
bool _isQueueEmpty(SqQueue Q) {
if (Q.rear==Q.front)
return true;
return false;
}
// 判断队列是否已满(非循环队列)不一定实用所有情况
bool _isQueueFull(SqQueue Q) {
if (Q.rear-Q.front+1==MaxSize)
return true;
return false;
}
// 入队
bool _EnQueue(SqQueue &Q, ElemType x) {
if(_isQueueFull(Q)) // 此处应该是判断队列是否满的操作,前面代码不一定实用所有情况
return false;
Q.data[Q.rear]=x;
Q.rear=Q.rear+1;
// Q.rear=(Q.rear+1)%MaxSize;
// 考虑把队列循环起来
return true;
/*
* 我们可以发现这种队列存储空间利用有限
* 当我们在入队的时候又有出队操作的时候
* 可以发现队尾指针 rear+1==MaxSize 的时候
* 我们会误以为队列已经满了
* front前面已经出队的位置没有能够充分利用
* 循环队列就出现了
*/}
// 判断队列是否为空
bool isQueueEmpty(SqQueue Q) {
if (Q.rear==Q.front)
return true;
return false;
}
// 判断队列是否已满
bool isQueueFull(SqQueue Q) {
if ((Q.rear+1)%MaxSize==Q.front)
return true;
return false;
}
// 入队
bool EnQueue(SqQueue &Q, ElemType e) {
if (isQueueFull(Q))
return false;
Q.data[Q.rear]=e;
Q.rear=(Q.rear+1)%MaxSize;
return true;
}
// 出队
bool DeQueue(SqQueue &Q, ElemType &x) {
if (isQueueEmpty(Q))
return false;
x=Q.data[Q.front];
Q.front=(Q.front+1)%MaxSize;
return true;
}
// 获取队头元素
bool QueueGetHead(SqQueue Q, ElemType &x) {
if (isQueueEmpty(Q))
return false;
x=Q.data[Q.front];
return true;
}

// 队列的链式实现
typedef struct QLNode { // 链式队列的节点
ElemType data;
struct QLNode *next;
}QLNode;

typedef struct { // 链式队列
QLNode *front, *rear; // 队列的队头和队尾指针
}LinkQueue;

// 初始化(带头节点)
void InitQueue_WithHeadNode(LinkQueue &Q) {
// 初始化的时候 front, rear 都指向头节点
Q.front=Q.rear=(QLNode *)malloc(sizeof(QLNode));
Q.front->next=NULL;
}
// 判断是否为空(带头节点)
bool isLinkQueueEmpty_WithHeadNode(LinkQueue Q) {
if (Q.front==Q.rear)
return true;
return false;
}
// 初始化(不带头节点)
void InitQueue_WithOutHeadNode(LinkQueue &Q) {
// 初始时 front, rear 都指向NULL
Q.front=NULL;
Q.rear=NULL;
}
// 判断是否为空(不带头节点)
bool isLinkQueueEmpty_WithOutHeadNode(LinkQueue Q) {
if (Q.front==NULL)
return true;
return false;
}
// 入队(带头节点)
void EnLQueue_WithHeadNode(LinkQueue &Q, ElemType x) {
QLNode *s=(QLNode *)malloc(sizeof(QLNode));
s->data=x;
s->next=NULL;
Q.rear->next=s; // 新节点插入到 rear->next 节点之后
Q.rear=s; // 修改 rear 指针;
}
// 入队(不带头节点)
void EnLQueue_WithOutHeadNode(LinkQueue &Q, ElemType x) {
QLNode *s=(QLNode *)malloc(sizeof(QLNode));
s->data=x;
s->next=NULL;
if (Q.front==NULL) { // 第一个元素特殊处理
Q.front=s;
Q.rear=s;
} else {
Q.rear->next=s; // 新节点插入到 rear->next 节点之后
Q.rear=s; // 修改 rear 指针
}
}
// 出队(带头结点)
bool DeLQueue_WithHeadNode(LinkQueue &Q, ElemType &x) {
if (Q.front==Q.rear)
return false; // 空队
QLNode *p=Q.front->next;
x=p->data; // x 返回的是队头元素
Q.front->next=p->next; // 头节点的 next 指向 p->next (该删除的的元素的下一个元素)
if (Q.rear==p) // 如果是最后一个节点
Q.rear=Q.front;
free(p);
return true;
}
// 出队(不带头结点)
bool DeLQueue_WithOutHeadNode(LinkQueue &Q, ElemType &x) {
if (Q.front==NULL)
return false; // 队空
QLNode *p=Q.front;
x=p->data;
Q.front=p->next;
if (Q.rear==p) {
Q.front=NULL;
Q.rear=NULL;
}
free(p);
return true;
}
  • Title: Stack and Queue的模板案例
  • Author: EaborH
  • Created at : 2025-07-28 00:00:00
  • Updated at : 2025-08-26 19:35:02
  • Link: https://eabor.xyz/2025/07/28/Stack and Queue/
  • License: This work is licensed under CC BY-NC-SA 4.0.
On this page
Stack and Queue的模板案例