數據結構與算法之——兩棧共享存儲空間

其實棧的順序存儲很方便,因爲它只在表尾進行操作,不存在普通線性表插入與刪除還需要移動元素的情況。同樣它也有普通線性表的缺陷,即必須確定數量。然而對於兩個相同類型的棧,卻可以做到最大限度地利用其開闢的存儲空間來進行操作。

         數組有兩個端點,兩個棧使用這一個數組的存儲區域,兩個棧有兩個棧底,分別爲數組的始端和末端。

這樣在壓棧的時候,是棧頂指針往中間靠攏,當兩指針相遇時,則棧滿。棧空即top1=-1,top2=n。而棧滿則是top1 + 1 == top2;

代碼實現:

SqDoubleStack.h

/*兩棧共享空間--順序棧結構 */

#define MAXSIZE 5
typedef int SElemType;
typedef struct
{
	SElemType data[MAXSIZE];
	int top1;	//棧1 棧頂指針
	int top2;	//棧2 棧頂指針
}SqDoubleStack;

#define OK 1
#define ERROR 0
typedef int Status;

Status InitStack(SqDoubleStack *S);	//初始化操作,建立一個空棧S
Status DestroyStack(SqDoubleStack *S);	//棧棧存在,則銷燬它
Status ClearStack(SqDoubleStack *S);	//將棧清空
int StackEmpty(SqDoubleStack S,int stackNumber);	//若棧爲空,返回true,否則返回false
Status GetTop(SqDoubleStack S,SElemType *e,int stackNumber);	//若棧存在且非空,用e返回S的棧頂元素
Status Push(SqDoubleStack *S,SElemType e,int stackNumber);	//若棧S存在,將新元素e插入棧S中併成爲棧頂元素
Status Pop(SqDoubleStack *S,SElemType *e,int stackNumber);	//刪除棧S中棧頂元素,並用e返回其值
int StackLength(SqDoubleStack S,int stackNumber);	//返回棧S的長度

SqDoubleStack.c

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include "SqDoubleStack.h"

int main(void)
{
	SqDoubleStack S;
	InitStack(&S);
	printf("已初始化好,現在壓棧1,2,3,4");
	Push(&S,1,1);
	Push(&S,2,1);
	Push(&S,3,2);
	Push(&S,4,2);
	Push(&S,5,2);
	printf("\n現在棧1的長度是:%d,棧2的長度是%d\n",StackLength(S,1),StackLength(S,2));
	printf("現在依次彈棧:");
	SElemType e ;
	Pop(&S,&e,1);
	printf("%d,",e);
	Pop(&S,&e,1);
	printf("%d,",e);
	Pop(&S,&e,2);
	printf("%d,",e);
	Pop(&S,&e,2);
	printf("%d,",e);
	Pop(&S,&e,2);
	printf("%d,",e);
	printf("\n現在棧1的長度是:%d,棧2的長度是%d\n",StackLength(S,1),StackLength(S,2));
	return 0;
}

Status InitStack(SqDoubleStack *S)	//初始化操作,建立一個空棧S
{
	memset(S->data,0,sizeof(SElemType)*MAXSIZE);//數組各元素初始化爲0
	S->top1 = -1;
	S->top2 = MAXSIZE;
	return OK;
}
Status DestroyStack(SqDoubleStack *S)	//棧棧存在,則銷燬它
{
	//free(S);
	return OK;
}
Status ClearStack(SqDoubleStack *S)	//將棧清空
{
	memset(S->data,0,sizeof(SElemType)*MAXSIZE);
	S->top1 = -1;
	S->top2 = MAXSIZE;
	return OK;
}
int StackEmpty(SqDoubleStack S,int stackNumber)	//若棧爲空,返回true,否則返回false
{
	if(1==stackNumber)
	{
		return S.top1 == -1;
	}
	else if(2==stackNumber)
	{
		return S.top2 == MAXSIZE;
	}
	return 0;
}
Status GetTop(SqDoubleStack S,SElemType *e,int stackNumber)	//若棧存在且非空,用e返回S的棧頂元素
{
	if(1==stackNumber)
	{
		if(StackEmpty(S,1))
		{
			return ERROR;
		}
		*e = S.data[S.top1];
		return OK;

	}
	else if(2==stackNumber)
	{
		if(StackEmpty(S,2))
		{
			return ERROR;
		}
		*e = S.data[S.top2];
		return OK;
	}
	return ERROR;
}
Status Push(SqDoubleStack *S,SElemType e,int stackNumber)	//若棧S存在,將新元素e插入棧S中併成爲棧頂元素
{
	if(S->top1 +1  == S->top2)
	{
		return ERROR;//已滿
	}
	if(1==stackNumber)
	{
		S->top1++;
		S->data[S->top1] = e;
		return OK;
	}
	else if(2==stackNumber)
	{
		S->top2--;
		S->data[S->top2] = e;
		return OK;
	}
	return ERROR;
}
Status Pop(SqDoubleStack *S,SElemType *e,int stackNumber)	//刪除棧S中棧頂元素,並用e返回其值
{
	if(StackEmpty(*S,stackNumber))
	{
		return ERROR;//爲空
	}
	if(1==stackNumber)
	{
		*e = S->data[S->top1];
		S->top1--;
		return OK;

	}
	else if(2==stackNumber)
	{
		*e = S->data[S->top2];
		S->top2++;
		return OK;
	}
	return ERROR;
}
int StackLength(SqDoubleStack S,int stackNumber)	//返回棧S的長度
{	
	if(1==stackNumber)
	{
		return S.top1+1;
	}
	else if(2==stackNumber)
	{
		return MAXSIZE-S.top2;
	}
	return -1;
}

事實上,使用這樣的數據結構,通常都是當兩個棧的空間需求有相反關係時,也即一個棧增長時,另一個棧在縮短。這樣使用兩棧共享空間存儲方法纔有比較大的意義,否則兩個棧都在不停地增長,那很快就會有棧滿而溢出。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章