现在这里插个链接,这是笔者之前写的一篇文章,讲的是基础版的栈,如果对栈不太熟悉可以先看看这一篇文章。
引入
上一篇文章我们学到了栈的顺序存储,这种方法只允许在栈顶针对元素进行操作,所以他并不存在像线性表一样在插入或删除操作时考虑移动元素的问题。但是他的缺陷也很明显,就是在开始我们就需要确定数组的空间的大小,万一不够用了,我们就需要使用编程手段来进行扩容(栈的链式存储),相当麻烦。但是相对的,如果有两个相同类型的栈,我们的操作空间就会更大一些。
打个比方说,两个大学室友毕业同时去武汉工作。刚开始时,他们觉得住了这么就得集体宿舍,现在工作了,应该有一点属于自己的空间。所以他们决定租一间独住的一间房间,但是在他们仔细调研之后,发现最便宜的也得一千五,距离工作的地方还很远,实在是承受不起。最终他们还是合租了一间两居室,一共两千,各出一半。
同样的道理,我们有两个相同类型的栈,我们为他们各自开辟了数组空间,可能是第一个栈的空间已经满了,但是第二个栈的空间还剩余很多,这肯定不合理,完全可以使用一个数组来存储两个栈。
因此,我们的做法如下图所示
数组有两个端点,两个栈有两个栈底,所以我们使用一个栈的栈底放在数组的起始处,另一个栈底放在数组的另一端。这样的话,我们在增加元素的时候就从两端点向中间延伸。
所以,我们的思路就是这样:
两个栈在数组的两端,分别向中间去延伸。top1和top2是栈1和栈2的栈顶指针,所以我们也得知了判断栈满的条件就是S.top2 - S.top1 == 1。
结构代码
typedef struct
{
ElementType data[MaxSize];
int top1;// 指向栈1的栈顶
int top2;// 指向栈2的栈顶
} SqShared_Stack;
初始化
void InitStack(SqShared_Stack &S)
{
S.top1 = -1;
S.top2 = MaxSize;
}
将两个栈的栈顶指针分别置于数组的两端
判空
bool isEmpty(SqShared_Stack S)
{
if (S.top1 == -1 && S.top2 == MaxSize)
{
return true;
}
else
{
return false;
}
}
S.top1 == -1 && S.top2 == MaxSize 与我们初始化时的条件时一样的,所以我们认为他是空栈。
判满
bool isFull(SqShared_Stack S)
{
if (S.top2 - S.top1 == 1)
{
return true;
}
else
{
return false;
}
}
这个地方就和我们前面说的一样了, 两栈的栈顶重合了,我们就认为此时栈是满的。
入栈
bool Push(SqShared_Stack &S, ElementType x, int flag)
//此处的flag是为了进行区别插入哪一个栈
{
if (isFull(S))
{
cout << "The Shared_Stack is full!" << endl;
return false;
}
else
{
if (flag == 1)
{
S.data[++S.top1] = x;
return true;
}
else if (flag == 2)
{
S.data[--S.top2] = x;
return true;
}
else
{
cout << "The flag is wrong!" << endl;
return false;
}
}
}
出栈
bool Pop(SqShared_Stack &S, ElementType &x,int flag)
{
if (isFull(S))
{
cout << "The Shared_Stack is empty!" << endl;
return false;
}
else
{
if (flag == 1)
{
x = S.data[S.top1--];
return true;
}
else if (flag == 2)
{
x=S.data[S.top2++];
return true;
}
else
{
cout << "The flag is wrong!" << endl;
return false;
}
}
}
获取栈顶元素
bool GetTop(SqShared_Stack S, ElementType &x, int flag)
{
if (isEmpty(S))
{
cout << "The Shared_Stack is empty!" << endl;
return false;
}
else
{
if (flag == 1)
{
x = S.data[S.top1];
return true;
}
else if (flag == 2)
{
x = S.data[S.top2];
return true;
}
else
{
cout << "The flag is wrong!" << endl;
return false;
}
}
}
这些基础操作做完了之后就是我们的测试环节了。
测试环节
SqShared_Stack S;
InitStack(S);
// 测试入栈
cout << "将元素推送到堆栈 1:" << endl;
for (int i = 1; i <= 5; i++)
{
Push(S, i, 1);
}
Display(S);
cout << "将元素推入堆栈 2:" << endl;
for (int i = 10; i <= 15; i++)
{
Push(S, i, 2);
}
Display(S);
// 测试获取栈顶元素
ElementType top;
GetTop(S, top, 1);
cout << "堆栈 1 的顶部元素: " << top << endl;
GetTop(S, top, 2);
cout << "堆栈 2 的顶部元素: " << top << endl;
// 测试出栈
ElementType popped;
cout << "从堆栈1中弹出元素:" << endl;
for (int i = 0; i < 3; i++)
{
Pop(S, popped, 1);
cout << "弹出 :" << popped << endl;
}
cout << "此时栈中的元素为:";
Display(S);
cout << "从堆栈2中弹出元素:" << endl;
for (int i = 0; i < 3; i++)
{
Pop(S, popped, 2);
cout << "弹出 :" << popped << endl;
}
cout << "此时栈中的元素为:";
Display(S);
// 测试判断栈是否为空或已满
cout << "堆栈是空的吗? " << (isEmpty(S) ? "是" : "不是") << endl;
cout << "堆栈是满的吗? " << (isFull(S) ? "是" : "不是") << endl;
标签:两栈,栈顶,top2,top1,数组,空间,共享,Stack,SqShared From: https://blog.csdn.net/shouyeren153/article/details/141759930