知识点导航:【数据结构】栈和队列
[王道数据结构]习题导航: p a g e 85.3 page85.3 page85.3
本节为栈和队列的综合练习题 |
思路:双栈模拟
思路分析:
由于队列是先进先出的,而栈先进后出,所以需要定义两个栈来实现先进先出:先进 S 1 S1 S1 → → → 后出 S 1 S1 S1 → → → 后进 S 2 S2 S2 → → → 先出 S 2 S2 S2
step:
算法思路:利用栈 S 1 S1 S1与 S 2 S2 S2来模拟一个队列,当需要入队时,用 S 1 S1 S1来存放已入队的元素,则压入 S 1 S1 S1的栈顶;出队时,则将 S 2 S2 S2的栈顶元素出栈
1.实现栈的基本操作
①定义结构体 + + + 初始化
由于为顺序栈,初始化即让 S.top==-1
#define Maxsize 50
typedef struct SqStack {
int data[Maxsize];
int top;
}SqStack;
//1.初始化
void InitStack(SqStack& S) {
S.top = -1;
}
②判空&判满
对于顺序栈来说,判空为:S.top==-1
;判满为:S.top==Maxsize-1
// 2.判满
bool Stackoverflow(SqStack& S) {
if (S.top == Maxsize-1)
return true;
return false;
}
// 3.判空
bool Stackempty(SqStack& S) {
if (S.top == -1)
return true;
return false;
}
③入栈
压入栈时,要判断栈是否已满,再让:S.data[++S.top]=x;
// 4.入栈
bool Push(SqStack& S, int x) {
if (Stackoverflow(S))
return false;
S.data[++S.top] = x;
return true;
}
④出栈
出栈时,先判断栈是否为空,再让:x=S.data[S.top--];
// 5.出栈
bool Pop(SqStack& S, int& x) {
if (Stackempty(S))
return false;
x = S.data[S.top--];
return true;
}
2.用栈实现队列操作
1.入队算法:
x x x入队时,是对入队栈 S 1 S1 S1 进行进栈操作,会出现几种情况:
①如果 S 1 S1 S1不为栈满状态,则直接将 x x x压入 S 1 S1 S1中:
②如果 S 1 S1 S1栈满,而 S 2 S2 S2栈为空,则先将 S 1 S1 S1中的所有元素压入栈 S 2 S2 S2中,再将 x x x压入S1中:
相当于先将输入的内容放入输出缓存区,这时候清空了输入条,则又可以继续输入了
③如果 S 1 S1 S1栈满,而 S 2 S2 S2栈为非空状态,则入队失败:
同时这也意味着此时 队满:Stackoverflow(S1) && !Stackempty(S2)
哪也去不了!
入队代码实现:
// 6.入队
bool Enqueue(SqStack& S1, SqStack& S2, int x) {
if (!Stackempty(S1)) { //如果S1不满 直接放到S1中
Push(S1, x);
return true;
}
else if (Stackoverflow(S1) && Stackempty(S2)) { //②如果S1满 而S2为空
while (!Stackempty(S1)) { //将S1中所有元素压入S2中,再将x压入S1中
int tmp;
Pop(S1, tmp);
Push(S2, tmp);
}
Push(S1, x);
return true;
}
else if (Stackoverflow(S1) && Stackempty(S2)) { //如果S1满且S2不为空 则无法入队
cout << "队列已满!" << endl;
return false;
}
}
2.出队算法:
由于从栈中取出元素是逆序的,所以必须先将 S 1 S1 S1中的所有元素依次出栈并压入 S 2 S2 S2中,在 S 2 S2 S2中进行出栈操作,而对出队栈 S 2 S2 S2的情况进行讨论:
①如果 S 2 S2 S2不为栈空,则直接将 S 2 S2 S2的栈顶元素弹出:
②如果 S 2 S2 S2为栈空,而 S 1 S1 S1不为空,则将 S 1 S1 S1中所有元素出栈并压入栈 S 2 S2 S2中,再对 S 2 S2 S2进行出栈:
③如果 S 1 S1 S1和 S 2 S2 S2均为空栈:
则出队失败,并且这也意味着此时 队空: Stackempty(S1) && Stackempty(S2)
代码实现:
// 7.出队
bool Dequeue(SqStack& S1,SqStack& S2,int &x) {
if (!Stackempty(S2)) { //如果S2不空
Pop(S2, x);
return true;
}
else if (!Stackempty(S1) && Stackempty(S2)) { //如果S2空但S1不空
while (!Stackempty(S1)) {
Pop(S1, x);
Push(S2, x);
}
Pop(S2, x);
return true;
}
else if (Stackempty(S1) && Stackempty(S2)) {
cout << "队列已空!" << endl;
return false;
}
}
3.队空&队满:
由上述可知:
Stackempty(S1) && Stackempty(S2)
Stackoverflow(S1) && !Stackempty(S2)
代码实现:
// 8.队列的判空
bool QueueEmpty(SqStack& S1, SqStack& S2) {
if (Stackempty(S1) && Stackempty(S2))
return true;
return false;
}
// 9.队满的判断
bool QueueOver(SqStack& S1, SqStack& S2) {
if (Stackoverflow(S1) && !Stackempty(S2))
return true;
return false;
}
完整代码实现:
#include
#define Maxsize 50
using namespace std;
typedef struct SqStack {
int data[Maxsize];
int top;
}SqStack;
// 1.初始化
void InitStack(SqStack& S) {
S.top = -1;
}
// 2.判满
bool Stackoverflow(SqStack& S) {
if (S.top == Maxsize-1)
return true;
return false;
}
// 3.判空
bool Stackempty(SqStack& S) {
if (S.top == -1)
return true;
return false;
}
// 4.入栈
bool Push(SqStack& S, int x) {
if (Stackoverflow(S))
return false;
S.data[++S.top] = x;
return true;
}
// 5.出栈
bool Pop(SqStack& S, int& x) {
if (Stackempty(S))
return false;
x = S.data[S.top--];
return true;
}
// 6.入队
bool Enqueue(SqStack& S1, SqStack& S2, int x) {
if (!Stackempty(S1)) { //如果S1不满 直接放到S1中
Push(S1, x);
return true;
}
else if (Stackoverflow(S1) && Stackempty(S2)) { //②如果S1满 而S2为空
while (!Stackempty(S1)) { //将S1中所有元素压入S2中,再将x压入S1中
int tmp;
Pop(S1, tmp);
Push(S2, tmp);
}
Push(S1, x);
return true;
}
else if (Stackoverflow(S1) && Stackempty(S2)) { //如果S1满且S2不为空 则无法入队
cout << "队列已满!" << endl;
return false;
}
}
// 7.出队
bool Dequeue(SqStack& S1,SqStack& S2,int &x) {
if (!Stackempty(S2)) { //如果S2不空
Pop(S2, x);
return true;
}
else if (!Stackempty(S1) && Stackempty(S2)) { //如果S2空但S1不空
while (!Stackempty(S1)) {
Pop(S1, x);
Push(S2, x);
}
Pop(S2, x);
return true;
}
else if (Stackempty(S1) && Stackempty(S2)) {
cout << "队列已空!" << endl;
return false;
}
}
// 8.队列的判空
bool QueueEmpty(SqStack& S1, SqStack& S2) {
if (Stackempty(S1) && Stackempty(S2))
return true;
return false;
}
// 9.队满的判断
bool QueueOver(SqStack& S1, SqStack& S2) {
if (Stackoverflow(S1) && !Stackempty(S2))
return true;
return false;
}
int main() {
SqStack S1;
SqStack S2;
InitStack(S1);
InitStack(S2);
//初始化队列元素
cout<<"请输初始化队列元素:" << endl;
int x;
while(cin>>x){
Push(S1, x);
if (cin.get() == '\n')
break;
}
//入队
cout<<"向队列中添加一个元素:" << endl;
cin >> x;
Enqueue(S1, S2, x);
//出队
cout<<"请输入要出队的元素个数:" << endl;
int n;
cin >> n;
cout << "出队元素依次为:" << endl;
int a=0;
for (int i = 0; i < n; i++) {
if (Dequeue(S1, S2, a))
cout << a << " ";
else
break;
}cout << endl;
system("pause");
return 0;
}
输出结果: