两栈共享空间(数组)

本文探讨了两栈共享空间的数据结构设计,通过代码示例展示了如何在数组中实现两个栈的共享空间,强调了在栈1和栈2之间进行push和pop操作的注意事项。并指出这种结构适用于空间需求相反的场景,如股票买卖操作,以避免快速溢出。但不同数据类型的栈可能使问题复杂化。

两栈共享空间(数组)

本文参考资料:《大话数据结构》

两栈共享空间

两栈共享空间的结构代码

/* 两栈共享空间结构 */
typedef struct
{
    SElemType data[MAXSIZE];
    int top1;	//栈1栈顶指针
    int top2;	//栈2栈顶指针
}SqDoubleStack;

对于两栈共享空间的push方法,除了要插入元素值参数外,还需要有一个判断是栈1还是栈2的栈号参数stackNumber;

/* 插入元素e为新的栈顶元素 */
Status Push(SqDoubleStack *S, SElemType e, int stackNumber)
{
    if(S->top1+1 == S->top2)	//栈已满,不能再push新元素了
        return ERROR;
    if(stackNumber == 1)	//栈1有元素进栈
        S->data[++S->top1] = e;	//若栈1则先top1+1后给数组元素赋值
    else if(stackNumber == 2)	//栈2有元素进栈
        S->data[--S->top2] = e;	//若栈2则先top2-1后给数组元素赋值
    return OK;
}

​ 因为在开始已经判断了是否有栈满的情况,所以后面的top1+1或top2-1是不担心溢出问题的。

​ 对于两栈共享空间的pop方法,参数就只是判断栈1栈2的参数stackNumber,代码如下:

/* 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR */
Status Pop(SqDoubleStack *S,SElemType *e, int stackNumber)
{
    if(stackNumber == 1)
    {
        if(S->top1 == -1)
            return ERROR;	//说明栈1已经是空栈,溢出
        *e = S->data[S->top1--];	//将栈1的栈顶元素出栈
    } else if(stackNumber == 2){
        if(S->top2 == MAXSIZE)
            return ERROR;	//说明栈2已经是空栈,溢出
        *e = S->data[S->top2++];	//将栈2的栈顶元素出栈
    }
    return OK;
}

​ 事实上,使用这样的数据结构,通常是当两个栈的空间需求有相反关系时,也就是一个栈增长时另一个栈在缩短的情况。就像买买股票,你买入时,一定是有一个你不知道的让人在做卖出操作。有人赚钱,就一定是有人赔钱。这样使用两栈共享空间存储方法才有比较大的意义。否则两个栈都在不停地增长,那很快就会因栈满而溢出了。

​ 当然了,这只是针对两个具有相同数据类型的栈的一个设计上的技巧,如果不是相同的数据类型,这种方法不但不能更好地处理问题,反而会使问题变得更复杂。

#include <stdio.h>
#include <stdbool.h>
#define MAXSIZE 100
#define ERROR 0
#define OK 1
typedef int SElemType;
typedef int Status;
typedef struct{
	SElemType data[MAXSIZE];
	int top1;	//栈1栈顶指针
	int top2;	//栈2栈顶指针 
}SqDoubleStack;

/* 入栈 */
Status push(SqDoubleStack* S, int stackNum, SElemType e){
	if(S->top1+1 == S->top2)	//栈满 
		return ERROR;
	if(stackNum == 1){
		S->data[++S->top1] = e;
	}else{
		S->data[--S->top2] = e;
	}
	return OK;
}

/* 出栈 */
Status pop(SqDoubleStack* S, int stackNum, SElemType *e){
	if(stackNum == 1){
		if(S->top1 == -1){	//栈空 
			return ERROR;
		}
		*e = S->data[S->top1--];
		return OK;
	}else{
		if(S->top2 == MAXSIZE){	//栈空 
			return ERROR;
		}
		*e = S->data[S->top2++];
		return OK;
	}
}

/* 返回栈顶元素 */
SElemType getTop(SqDoubleStack* S, int stackNum, SElemType* e){
	if(stackNum == 1){
		if(S->top1 == -1){	//栈空 
			return ERROR;
		}
		*e = S->data[S->top1];
		return OK;
	}else{
		if(S->top2 == MAXSIZE){	//栈空 
			return ERROR;
		}
		*e = S->data[S->top2];
		return OK;
	}
}

/* 栈空 */
bool stackEmpty(SqDoubleStack* S, int stackNum){
	if(stackNum == 1){
		if(S->top1 == -1)
			return true;
		return false;
	}else{
		if(S->top2 == MAXSIZE)
			return true;
		return false;
	}
}

/* 栈满 */
bool stackFull(SqDoubleStack* S){
	if(S->top1+1 == S->top2)
		return true;
	return false;
} 

/* 栈元素遍历 */
void printStack(SqDoubleStack* S){
	if(stackEmpty(S, 1) && stackEmpty(S, 2)){
		printf("栈空!\n");
		return;
	}
	int i = 0;
	printf("栈中元素遍历:\n");
	printf("栈1元素集:\n");
	while(i<=S->top1)
		printf("%d\n", S->data[i++]);
	printf("栈2元素集:\n");
	i=MAXSIZE-1;
	while(i>=S->top2)
		printf("%d\n", S->data[i--]);
}

/* 栈长度 */
int stackLength(SqDoubleStack* S, int stackNum){
	if(stackNum == 1)
		return S->top1+1;
	else
		return MAXSIZE-S->top2;
}

int main(){
	
	bool continueFlag = true;
	SElemType popNum, pushNum;
	SqDoubleStack doubleStack, *S = &doubleStack;
	doubleStack.top1 = -1;
	doubleStack.top2 = MAXSIZE;
	int stackNum;
	int functionNum;
	while(continueFlag){
		printf("-----------菜单------------\n");
		printf("-----------1.入栈----------\n");
		printf("-----------2.出栈----------\n");
		printf("-----------3.返回栈顶元素--\n");
		printf("-----------4.栈元素遍历----\n");
		printf("-----------5.栈元素个数----\n");
		printf("-----------6.判断栈是否为空\n");
		printf("-----------7.判断栈是否已满\n");
		printf("-----------8.退出----------\n");
		printf("输入功能号:\n");
		scanf("%d",&functionNum);
		printf("-----------------------\n");
		switch(functionNum){
			case 1:
				printf("选择栈(1或2):\n");
				scanf("%d", &stackNum);
				printf("请输入要入栈的元素:\n");
				scanf("%d", &pushNum);
				if(push(S, stackNum, pushNum))
					printf("入栈成功!\n");
				else
					printf("入栈失败!\n");
				break;
			case 2:
				printf("选择栈(1或2):\n");
				scanf("%d", &stackNum);
				if(pop(S, stackNum, &popNum))
					printf("出栈元素:%d\n",popNum);
				else
					printf("栈空!\n");
				break;
			case 3:
				printf("选择栈(1或2):\n");
				scanf("%d", &stackNum);
				if(getTop(S, stackNum, &popNum))
					printf("栈顶元素:%d!\n",popNum);
				else
					printf("栈空!\n");
				break;
			case 4:
				printStack(S);
				break;
			case 5:
				printf("选择栈(1或2):\n");
				scanf("%d", &stackNum);
				printf("栈元素个数:%d\n",stackLength(S, stackNum));
				break;
			case 6:
				printf("选择栈(1或2):\n");
				scanf("%d", &stackNum);
				if(stackEmpty(S, stackNum))
					printf("栈空!\n");
				else
					printf("栈非空!\n");
				break;
			case 7:
				if(stackFull(S))
					printf("栈满!\n",popNum);
				else
					printf("栈不满!\n");
				break;
			case 8:
				continueFlag = false;
				printf("欢迎使用!\n");
				break;
			default:
				printf("功能号不存在!\n");
				break;
		}
		printf("-----------------------\n");
	}
	return 0;
} 
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值