数据结构与算法(6)— 多栈
3、多栈
3.1、常常在一个程序中要用到多个栈,为了不发生上溢错误,就必须给每个栈预先分配一个足够大的存储空间,但实际中很难准确估计。另一方面,若每个栈都预分配过大的存储空间,会造成系统资源的浪费。若让多个栈共用一个足够的的连续存储空间,则可利用栈的动态特性使它们的存储空间互补。在栈的共享中最常见的是两个栈共享。假设两个栈共享一维数组stack[MAXNUM],则可以利用栈的“栈底位置不变,栈顶位置动态变化”的特性,两个栈底分别为-1和MAXNUM,而他们的栈顶都往中间方向延伸。因此,只要整个数组未被占满,无论那个栈的入栈都不会发生上溢。在程序中同时使用两个以上的栈时,使用顺序栈共用邻接空间很不方便,但若用多个单链栈时,就很方便了,这涉及多个链栈的操作,可将多个单链栈的栈顶指针放在一个一维数组中来实现。
#include <stdio.h>
#define STACKSIZE 100
typedef int ElemType;
typedef struct bothstack{
ElemType data[STACKSIZE];/*STACKSIZE为整个存储空间的大小(所含单元数)*/
int top1; /*top1、top2分别为栈1和栈2的栈顶元素*/
int top2;
}BothStack;
enum BothStackNumber{FIRST,SECONDLY};
在这种双栈操作中,当对任一一个插入是若栈1的元素数+栈2的元素数=STACKSIZE-1(即top1=top2-1或top2=top1+1),则表示栈满;当对栈1或栈2进行删除时,若top1=0或top2=STACKSIZE,则表明相应的栈空。另外,当新元素压入栈2时,栈顶指针top2不是+1而是-1;当从栈2删除元素时,top2不是-1而是+1;
3.2、多栈基本函数算法描述
注:以下程序在VC6.0+WIN2K下测试通过。
/*置空栈算法*/
void SetNull(BothStack *bs,BothStackNumber k)
{
if(k==FIRST)
bs->top1=-1;
else
bs->top2=STACKSIZE;
}
/*插入算法*/
void push(BothStack *bs,ElemType x,BothStackNumber k)
{
if (bs->top1==(bs->top2-1))
printf("overflow");
if (k==FIRST)
{
bs->top1=bs->top1+1;
bs->data[bs->top1]=x;
}
else
{
bs->top2=bs->top2-1;
bs->data[bs->top2]=x;
}
}
/*删除算法*/
void pop(BothStack *bs,ElemType *x,BothStackNumber k)
{
if (k==FIRST) /*对第一个栈进行删除*/
{
if (bs->top1==-1)
printf("underflow");
*x=bs->data[bs->top1];
bs->top1=bs->top1-1;
}
else /*对第二个栈进行删除*/
{
if (bs->top2==STACKSIZE)
printf("underflow");
*x=bs->data[bs->top2];
bs->top2=bs->top2+1;
}
}
void show(BothStack bs,BothStackNumber k)
{
if(k==FIRST)
{
if(bs.top1==-1)
{
printf("栈1中没有元素/n");
return;
}
while(bs.top1!=-1)
{
printf("栈1的元素分别为:%d/n",bs.data[bs.top1]);
bs.top1=bs.top1-1;
}
}
else
{
if(bs.top2==STACKSIZE)
{
printf("栈2中没有元素/n");
return;
}
while(bs.top2!=STACKSIZE)
{
printf("栈2的元素分别为:%d/n",bs.data[bs.top2]);
bs.top2=bs.top2+1;
}
}
}
3.3、测试程序
int main()
{
BothStack BS;
ElemType X;
SetNull(&BS,FIRST);
SetNull(&BS,SECONDLY);
show(BS,FIRST);
show(BS,SECONDLY);
printf("/n/n");
push(&BS,1,FIRST);
push(&BS,2,FIRST);
push(&BS,3,FIRST);
push(&BS,3,SECONDLY);
push(&BS,2,SECONDLY);
push(&BS,1,SECONDLY);
show(BS,FIRST);
show(BS,SECONDLY);
printf("/n/n");
pop(&BS,&X,FIRST);
pop(&BS,&X,SECONDLY);
show(BS,FIRST);
show(BS,SECONDLY);
printf("/n/n");
pop(&BS,&X,FIRST);
pop(&BS,&X,SECONDLY);
pop(&BS,&X,FIRST);
pop(&BS,&X,SECONDLY);
show(BS,FIRST);
show(BS,SECONDLY);
return 1;
}