/*

共享栈

2018/8/4

利用栈底位置不对称性,可以让两个顺序栈共享一个一维数据空间,
将两个栈的栈底分别设置为共享空间的两端,两个栈顶向共享空间中间延伸,
两个栈的栈顶指针都指向了两个栈顶元素,
top1=-1时,栈1为空,top2=MAX_SIZE,栈2为空
栈顶指针相邻时(–top2 = top1)栈满,

共享栈为了更加有效的利用存储空间,同时只有整个存储空间被占满,发生上溢
*/

#include "stdio.h"
#include "stdlib.h"
#include "stdbool.h"
#include "malloc.h"'


#define MAX_SIZE 10
#define stack1 1
#define stack2 2

#define stack1Empty 2
#define stack2Empty 3

typedef struct SharedStack{
int *PBase;
int top1;
int top2;
}Stack,*PStack;


PStack CreateShareStack(void); //创建栈
bool ShareStackFull(PStack); //判满返1
int ShareStackEmpty( PStack S); //判空返1 2 3 0
int ShareStackPush(PStack S, int which, int val); //PUSH
int ShareStackPop(PStack S, int which, int *val); //pop
int ShareStackDisplay(PStack S); //printing


int main()
{
int val,i;
int a[10]={1,2,3,4,5,6,7,8,9,10};
PStack S = CreateShareStack();

for(i=0; i<5; i++)
{
ShareStackPush(S,stack1,i);
}

for(i=10; i>5; i--)
{
ShareStackPush(S,stack2,i);
}
ShareStackDisplay(S);
ShareStackPush(S,stack1,33);
ShareStackDisplay(S);
ShareStackPush(S,stack2,44);
ShareStackDisplay(S);

for(i=0; i<5; i++)//pop出三个
{
ShareStackPop(S,stack1,&val);
}
ShareStackDisplay(S);
ShareStackPop(S,stack1,&val);
ShareStackDisplay(S);


printf("\nHello world!\n");
return;
}



/* 创建共享栈 */
PStack CreateShareStack(void)
{
PStack S = (PStack)malloc(sizeof(Stack));
S->top1 = -1;
S->top2 = MAX_SIZE;
S->PBase = (int*)malloc(sizeof(int) * MAX_SIZE);
printf("Success create stack!\n");
return S;
}

/* 判为满 返1 */
bool ShareStackFull(PStack S)
{
return ((S->top2 - 1) == S->top1 ) ? true:false;
}

/* 判为空 全空返1 全不空返0 栈1空返2 栈2空返3 */
int ShareStackEmpty( PStack S)
{
if( (S->top1 == -1) && (S->top2 == MAX_SIZE) )
{
printf("两栈全空\n");return 1;
}
if(S->top1 == -1 && S->top2 != MAX_SIZE ) return stack1Empty; //栈1空
if(S->top1 != -1 && S->top2 == MAX_SIZE ) return stack2Empty; //栈2空
else return 0;
}

/* val Push 到 第which 栈 */
int ShareStackPush(PStack S, int which, int val)
{
if(ShareStackFull(S))
{
printf("栈空间已满,请释放空间后在压栈!\n");return;
}
if(which == stack1)
{
S->PBase[++S->top1] = val;
}else
{
S->PBase[--S->top2] = val;
}
return;
}

/* Pop 第which 栈 到val */
int ShareStackPop(PStack S, int which, int *val)
{
int i = ShareStackEmpty(S); //1全空 0全不空 2 1空 3 2空
if(i == 1) return;

if(which == stack1)
if(i == 0 || i == 3)
{
*val = S->PBase[S->top1--] ;
} else if(i == 2)
{
printf("栈1已空\n");return;
}

if(which == stack2)
if(i == 0 || i == 2)
{
*val = S->PBase[S->top2++];
} else if(i == 3)
{
printf("栈2已空\n");return;
}
return;
}

/* 打印两个栈 */
int ShareStackDisplay(PStack S)
{
if(ShareStackEmpty(S) == 1)return;//两栈全空时取消打印
printf("栈1的有效数据: ");
int i;
for(i=0; i <= S->top1; i++)
{
printf("%d ",S->PBase[i]);
}

printf(" 栈2的有效数据: ");
i = MAX_SIZE - 1;

for(i=MAX_SIZE-1; i >= S->top2; i--)
{
printf("%d ",S->PBase[i]);
}
printf("\n");
}