一个数组实现两个栈(共享栈)

本文探讨了一种在单一数组中实现两个独立栈的有效方法。通过对比三种不同的实现方案,详细阐述了方法3的优势,即避免了空间浪费,实现了栈1和栈2的高效存储与操作。文章提供了具体的代码实现,包括栈的初始化、入栈、出栈和获取栈顶元素等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:
  一个数组实现两个栈。
方法1:
  下标为0的位置为栈1的栈底,下标为1的位置为栈2的栈底,栈1的元素存放在下标为偶数的位置上,栈2的元素放在下标为奇数的位置上。
这里写图片描述

  如上图所示的数组:若栈1有一个元素 2,栈2有6个元素 1,2,3,4,5,6,下标为0的位置为 2,下标为1,3,5,7,9的位置分别为1,2,3,4,5。6无法插入但数组中还有很多剩余的空间。。可见该方法会浪费大量的空间。

这里写图片描述


方法2:
  中间的两个下标分别作为栈1和栈2的栈底,栈1和栈2分别向左右扩展。
这里写图片描述
  如方法1所示,方法2与方法1相似也会浪费大量的空间。


方法3:
  下标为0的位置为栈1的栈底,栈2的栈底在下标最大的位置上。栈1向左扩展,栈2向后扩展。这种方法不会出现浪费内存的情况。
这里写图片描述


方法3的代码实现:

  首先应该定义一个共享栈:

#define Max 10
#define DataType int 
typedef struct SharedStack
{
    DataType data[Max];
    int top1;
    int top2;
}sharedstack;

共享栈初始化:

//共享栈初始化
void InitShared(sharedstack *s)
{
    assert(s);
    s->top1 = 0;
    s->top2 = Max - 1;
    memset(s->data, 0, Max*sizeof(DataType));
}

入栈:

//入栈
void PushSharedStack(sharedstack *s, DataType d, int which)
{
    assert(s);
    if (which == 1)
    {
        if (s->top1 <= s->top2)
        {
            s->data[s->top1++] = d;
        }
        else
        {
            printf("栈已满!\n");
            return;
        }
    }
    else
    {
        if (s->top1 <= s->top2)
        {
            s->data[s->top2--] = d;
        }
        else
        {
            printf("栈已满!\n");
            return;
        }
    }
}
  which == 1 表示栈1,d表示要入栈的数据。

出栈:

//出栈
void PopSharedStack(sharedstack *s, int which)
{
    assert(s); 
    if (which == 1)
    {
        if (s->top1 == 0)
        {
            printf("栈空!\n");
            return;
        }
        else
        {
            s->top1--;
        }
    }
    else
    {
        if (s->top2 == Max-1)
        {
            printf("栈空!\n");
            return;
        }
        else
        {
            s->top2++;
        }
    }
}

栈顶元素:

//栈顶
DataType SharedStackTop(sharedstack *s, int which)
{
    assert(s);
    if (which == 1)
    {
        if (s->top1 == 0)
        {
            printf("栈空!\n");
            return -1;
        }
        else
            return s->data[s->top1 - 1];
    }
    else
    {
        if (s->top2 == Max-1)
        {
            printf("栈空!\n");
            return -1;
        }
        else
            return s->data[s->top2 + 1];
    }
}

栈长短:

//栈长短
DataType SharedStackSize(sharedstack *s, int which)
{
    assert(s);
    if (which == 1)
    {
        return s->top1;
    }
    else
        return Max - s->top2 - 1;
}
### 如何在单个数组实现两个 为了在一个数组实现两个,可以采用双端的方式。具体来说,在同一个数组两端分别设置两个底指针,一个指向数组起始位置作为第一个的底部(记作`bottom1`),另一个指向数组末尾作为第二个的顶部(记作`top2`)。当向任一中添加新元素时,相应调整该顶端的位置;而移除元素则相反。 #### 定义数据结构 定义一个包含这两个共享使用的数组以及各自独立维护的顶索引变量: ```c #define MAX_SIZE 100 // 假设最大容量为100 typedef struct { int data[MAX_SIZE]; int top1; /* 1 的顶 */ int top2; /* 2 的顶 */ } TwoStacks; ``` 初始化函数用于设定初始状态下的两个为空的状态: ```c void initTwoStacks(TwoStacks *ts) { ts->top1 = -1; // 初始化1为空 ts->top2 = MAX_SIZE; // 初始化2为空 } ``` #### 实现基本操作 ##### 插入元素 对于每个而言,插入意味着增加新的项并更新对应的顶指示器。需要注意的是要检查是否有足够的空间来容纳新增加的项目。 ```c int pushToStack1(TwoStacks *ts, int value){ if(ts->top1 + 1 >= ts->top2){return 0;} // 如果没有可用的空间,则失败 ts->data[++(ts->top1)] = value; return 1; } int pushToStack2(TwoStacks *ts, int value){ if(ts->top1 >= ts->top2 - 1){return 0;} // 如果没有可用的空间,则失败 ts->data[--(ts->top2)] = value; return 1; } ``` ##### 删除元素 从指定的弹出最上面的一项,并减少相应的顶计数器。 ```c int popFromStack1(TwoStacks *ts, int *value){ if(ts->top1 == -1){return 0;} // 当前已经为空 *value = ts->data[(ts->top1)--]; return 1; } int popFromStack2(TwoStacks *ts, int *value){ if(ts->top2 == MAX_SIZE){return 0;} // 当前已经为空 *value = ts->data[(ts->top2)++]; return 1; } ``` 通过这种方式可以在单一的一维数组内有效地管理两个独立运作但又相互关联的数据集合——即实现了所谓的“双向增长”的双模型[^5]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值