利用数组来实现栈,这个我们已经实现了。今天我们利用一个数组,来实现两个栈的操作。首先我们得考虑,一个数组怎么才能当做两个栈,这里我有两个思路。
- 在数组的两头开始相向而插。
- 在数组奇偶下标分别插入
考虑到我们两个栈的可延展性,我最终决定利用第二种方式来插入。具体思路如下:
首先我们要创建新的结构体来控制我们这个数组及其栈。
#pragma once
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
typedef char StackType;//定义栈内元素类型
typedef struct _2Stack_ByArray{
StackType *data;
size_t Stack1;//将来插入栈一时的下标
size_t Stack2;/插入栈二时的下标
size_t size1;//栈一元素个数
size_t size2;//栈二元素个数
size_t capacity; //栈总元素个数,可扩充
}_2Stack;
接下来应该有这个栈的基本操作:
//在这里,我们考虑到,在操作时可能仅仅只对其中某一个栈进行操作
//而不是二者同时进行,所以我们引进一个新的参数choose
//choose来确定要对哪个进行操作
void _2Stack_ByArrayInit(_2Stack* s);//初始化栈
void _2Stack_ByArrayEmpty(_2Stack* s, int choose);//清空栈
void _2Stack_ByArrayPush(_2Stack* s, StackType value, int choose);//入栈
void _2Stack_ByArrayPop(_2Stack* s, int choose);//出栈
int _2Stack_ByArrayTop(_2Stack* s, StackType* value, int choose);//取栈顶元素
接下来我们对里面的操作进行逐一实现
//初始化栈
void _2Stack_ByArrayInit(_2Stack* s)//初始化栈
{
if(s == NULL) {
return;
}
s->size1 = s->size2 = 0;//首先将两个栈内元素个数置为0
s->capacity = 1000;//给定元素个数
s->data = (StackType*)malloc(s->capacity * sizeof(StackType));//申请空间,以备扩容
s->Stack1 = 0;//栈一初始角标设为0
s->Stack2 = 1;//栈二初始角标设为1
return;
}
//清空栈
void _2Stack_ByArrayEmpty(_2Stack* s, int choose)//清空栈
{
if(s == NULL) {
return;
}
if(choose == 1) {//对栈一进行清空
s->size1 = 0;//注:清空时不仅仅要清空size,还要将其初始角标清空
s->Stack1 = 0;
} else {//对栈二进行清空
s->size2 = 0;
s->Stack2 = 1;
}
return;
}
//入栈
void _2Stack_ByArraySet(_2Stack* s) //扩容
{
if(s == NULL) {
return;
}
if(s->size1 + s->size2 < s->capacity) {//再次判断是否满,起到了双保险作用
return;
}
StackType* new_set = (StackType*)malloc(2*s->capacity*sizeof(StackType)+1);//这里加一是防止capacity为0
size_t i = 0;
for(; i < s->capacity; i++) {//拷贝原来栈内元素
new_set[i] = s->data[i];
}
s->data = new_set;
return;
}
void _2Stack_ByArrayPush(_2Stack* s, StackType value, int choose)//入栈
{
if(s == NULL) {
return;
}
if(s->size1 + s->size2 >= s->capacity) {
_2Stack_ByArraySet(s);//如果栈内元素满了,则扩容
}
if(choose == 1) {//这里与顺序栈入栈的操作一样,只是需要判断给栈一还是二进行入栈
s->data[s->Stack1] = value;
s->Stack1 += 2;
s->size1++;
}
else {
s->data[s->Stack2] = value;
s->Stack2 += 2;
s->size2++;
}
return;
}
//出栈
void _2Stack_ByArrayPop(_2Stack* s, int choose)//出栈
{
if(s == NULL) {
return;
}
if(choose == 1) {
if(s->size1 == 0) {//判断是否为空栈
return;
}
s->Stack1 -= 2;
s->size1--;
} else {
if(s->size2 == 0) {//判断是否为空栈
return;
}
s->Stack2 -= 2;
s->size2--;
}
return;
}
//取栈顶元素
int _2Stack_ByArrayTop(_2Stack* s, StackType* value, int choose)//取栈顶元素
{
if(s == NULL) {
return -1;
}
if(choose == 1) {
if(s->size1 == 0) {
return -1;
}
*value = s->data[s->Stack1-2];
return 1;
} else {
if(s->size2 == 0) {
return -1;
}
*value = s->data[s->Stack2-2];
return 1;
}
}
为了我们再测试时方便观察,我们对打印栈内元素进行实现。
//打印栈内元素
void _2Stack_ByArrayPrint(_2Stack* s, int choose)//打印栈
{
if(s == NULL) {
return;
}
if(choose == 1) {
size_t i = 0;
for(; i < s->Stack1; i+=2) {
printf("%c ",s->data[i]);
}
} else {
size_t i = 1;
for(; i < s->Stack2; i+=2) {
printf("%c ",s->data[i]);
}
}
printf("\n");
return;
}
下面是测试代码:
//测试代码如下
void TestPush()
{
HEAD;
_2Stack s;
_2Stack_ByArrayInit(&s);
_2Stack_ByArrayPush(&s,'a',1);
_2Stack_ByArrayPush(&s,'b',1);
_2Stack_ByArrayPush(&s,'c',1);
_2Stack_ByArrayPush(&s,'d',1);
_2Stack_ByArrayPrint(&s, 1);
_2Stack_ByArrayPush(&s,'x',2);
_2Stack_ByArrayPush(&s,'y',2);
_2Stack_ByArrayPush(&s,'z',2);
_2Stack_ByArrayPush(&s,'n',2);
_2Stack_ByArrayPrint(&s, 2);
_2Stack_ByArrayEmpty(&s, 1);
_2Stack_ByArrayPrint(&s, 1);
}
void TestPop()
{
HEAD;
_2Stack s;
_2Stack_ByArrayInit(&s);
_2Stack_ByArrayPop(&s, 2);
_2Stack_ByArrayPrint(&s, 1);
_2Stack_ByArrayPush(&s,'a',1);
_2Stack_ByArrayPush(&s,'b',1);
_2Stack_ByArrayPush(&s,'c',1);
_2Stack_ByArrayPush(&s,'d',1);
_2Stack_ByArrayPrint(&s, 1);
_2Stack_ByArrayPop(&s, 1);
_2Stack_ByArrayPrint(&s, 1);
_2Stack_ByArrayPush(&s,'x',2);
_2Stack_ByArrayPush(&s,'y',2);
_2Stack_ByArrayPush(&s,'z',2);
_2Stack_ByArrayPush(&s,'n',2);
_2Stack_ByArrayPrint(&s, 2);
_2Stack_ByArrayPop(&s, 2);
_2Stack_ByArrayPop(&s, 2);
_2Stack_ByArrayPrint(&s, 2);
}
void TestTop()
{
HEAD;
_2Stack s;
StackType value;
int ret;
_2Stack_ByArrayInit(&s);
ret = _2Stack_ByArrayTop(&s, &value, 1);
printf("expected ret -1, actual ret %d\n",ret);
_2Stack_ByArrayPush(&s,'a',1);
_2Stack_ByArrayPush(&s,'b',1);
_2Stack_ByArrayPush(&s,'c',1);
_2Stack_ByArrayPush(&s,'d',1);
_2Stack_ByArrayPrint(&s, 1);
ret = _2Stack_ByArrayTop(&s, &value, 1);
printf("expected ret 1, actual ret %d\n",ret);
printf("expected value d, actual ret %c\n",value);
_2Stack_ByArrayPush(&s,'x',2);
_2Stack_ByArrayPush(&s,'y',2);
_2Stack_ByArrayPush(&s,'z',2);
_2Stack_ByArrayPush(&s,'n',2);
_2Stack_ByArrayPrint(&s, 2);
ret = _2Stack_ByArrayTop(&s, &value, 2);
printf("expected ret 1, actual ret %d\n",ret);
printf("expected value n, actual ret %c\n",value);
}
int main()
{
TestPush();
TestPop();
TestTop();
printf("\n");
printf("\n");
printf("\n");
printf("\n");
printf("\n");
return 0;
}
欢迎大家共同讨论,如有错误及时联系作者指出,并改正。谢谢大家!