相比于普通的顺序栈,
共享栈主要是为了
提高内存的利用率和
减少溢出的可能性而设计的。
当两个栈共享一片连续的内存空间时,应将两栈的栈底分别设在这片内存空间的两端,这样,当两个栈的栈顶在栈空间的某一位置相遇,才产生上溢。
解释:两个栈共享一片连续的内存空间,可知两个栈都是顺序栈(顺序栈占用连续的存储空间),为顺序栈分配好的连续空间大小在栈的操作过程中不变,并且这个连续的存储空间有恒定不变的两端。可知,这两个栈的栈底分别位于存储空间的两端,确定了栈底,则两栈栈顶必在存储空间内,显然当两个栈顶相遇时,存储空间被用尽,产生上溢。
示意图如下(某个博客找到的,觉得非常形象)
第一个栈从数组头开始存储,第二个栈从数组尾开始,两个栈向中间拓展。
----------------------------------------------------------------------------------------------------------------------------------
完整代码如下:
#include <stdio.h>
#include <stdlib.h>
#define maxSize 100
typedef struct
{
int data[maxSize];
int top1;
int top2;
}Stack;
Stack s;
/**************初始化栈*****************/
int initStack()
{
s.top1 = -1;
s.top2 = maxSize; //这里就能看出,这个栈是个共享栈,是由2个栈组合而成,两个指针在两头
}
/***************进栈****************/
int push()
{
int flag1; //指示是第一个栈还是第二个栈
if (s.top1 + 1 == s.top2) //如果两个头指针碰到一起了,栈就满了
printf("栈满!");
printf("按1从top1存入,按2从top2存入。按回车键停止存入!\n");
scanf_s("%d", &flag1);
switch (flag1)
{
case 1:
printf("请输入栈1的数据:");
while (1)
{
s.top1++;
scanf_s("%d", &s.data[s.top1]);
//printf("%d ", s.data[s.top1]);
char c1 = getchar();
if (c1 == '\n')
break;
}
case 2:
printf("\n请输入栈2的数据:");
while (1)
{
--s.top2;
scanf_s("%d", &s.data[s.top2]);
//printf("%d ", s.data[s.top2]);
char c2 = getchar();
if (c2 == '\n')
break;
}
break;
}
return 1;
}
/********************出栈******************/
int pop()
{
int flag2; //指示是哪个栈
if (s.top1 == -1 && s.top2 == maxSize)
printf("\n栈内无数据,你出个什么栈---\n");
printf("按1从top1出栈,按2从top2出栈。按回车键停止!\n");
scanf_s("%d", &flag2);
printf("\n");
switch (flag2)
{
case 1:
printf("栈1出栈数据顺序为:");
while (s.top1 > -1)
{
printf("%d ", s.data[s.top1]);
s.top1--;
}
case 2:
printf("\n栈2出栈数据顺序为:");
while (s.top2 < maxSize)
{
printf("%d ", s.data[s.top2]);
s.top2++;
}
}
}
void main()
{
printf("这是一个共享栈!\n");
initStack();
push();
pop();
system("pause");
}
结果图如下: