通过一个数组实现两个栈(C语言)

原创 2018年04月17日 20:06:01

通过一个数组实现的两个栈也叫作共享栈。我们可以将一个数组一分为二,供两个栈使用。
这里写图片描述
也有另外一种虽然也是讲一个数组一分为二供两个栈使用,但在具体实现上有所不同。
牢记栈1的区间是[0,top1)的左闭右开区间,栈2的区间是[top2,max_size)的左闭右开区间。其中的top1位置并不存放栈1的值,而max_size是数组的边界值也取不到。
正式由于两个栈的区间的取值,所以当top1与top2相等时,两个栈就同时都满了。
这里写图片描述
显而易见的,方法2比方法1在空间利用率上更好,也更加契合生活的需求。
(比如说:我们的栈1只有5个元素需要入栈,而栈2有500个元素入栈,当采用方法1把数组一分为二,给两个栈分配了固定的空间,当栈2的元素放不下的时候,而我们的栈1还有大量的空间没有使用,如果采用方法2,栈1仅仅只会占据5个元素的空间,栈2就可以有更多的空间去存放500个元素。)
下面以代码实现方法二

ShareStack.h文件

#pragma once
#define max_size 10000

typedef char DataType;

typedef struct ShareStack
{
    DataType data[max_size];
    int top1;
    int top2;
}ShareStack;

//栈1的初始化
void ShareStack1Init(ShareStack *shareSatck);
//栈2的初始化
void ShareStack2Init(ShareStack *shareSatck);
//栈1的销毁
void ShareStack1Destroy(ShareStack *shareSatck);
//栈2的销毁
void ShareStack2Destroy(ShareStack *shareSatck);
//栈1的入栈操作函数
void ShareStack1Push(ShareStack *shareSatck,DataType value);
//栈2的入栈操作函数
void ShareStack2Push(ShareStack *shareSatck,DataType value);
//栈1的出栈操作函数
void ShareStack1Pop(ShareStack *shareSatck);
//栈2的出栈操作函数
void ShareStack2Pop(ShareStack *shareSatck);
//取栈1的栈顶元素操作函数
int ShareStack1Top(ShareStack *shareSatck,DataType *value);
//取栈2的栈顶元素操作函数
int ShareStack2Top(ShareStack *shareSatck,DataType *value);

ShareStack.c文件

#include<stdio.h>
#include"ShareStack.h"

#define Test_Header printf("\n==========%s==========\n",__FUNCTION__);

//栈1的初始化
void ShareStack1Init(ShareStack *shareSatck)
{
    if(shareSatck == NULL)
    {
        //非法输入
        return;
    }
    //直接将top1置为0,就表明栈1中没有任何元素
    shareSatck->top1 = 0;
}
//栈2的初始化
void ShareStack2Init(ShareStack *shareSatck)
{
    if(shareSatck == NULL)
    {
        //非法输入
        return;
    }
    //直接将top2置为max_size,就表明栈2中没有任何元素
    shareSatck->top2 = max_size;
}
//栈1的销毁
void ShareStack1Destroy(ShareStack *shareSatck)
{
    if(shareSatck == NULL)
    {
        //非法输入
        return;
    }
    //直接将top1置为0,就表明栈1中没有了任何元素
    shareSatck->top1 = 0;
    shareSatck->data[shareSatck->top1] = 0;
}
//栈2的销毁
void ShareStack2Destroy(ShareStack *shareSatck)
{
    if(shareSatck == NULL)
    {
        //非法输入
        return;
    }
    //直接将top2置为max_size,就表明栈2中没有任何元素
    shareSatck->top2 = max_size;
}
//栈1的入栈操作函数
void ShareStack1Push(ShareStack *shareSatck,DataType value)
{
    if(shareSatck == NULL)
    {
        //非法输入
        return;
    }
    if(shareSatck->top1 == shareSatck->top2 || shareSatck->top1 == max_size)
    {
        //栈1满了
        return;
    }
    //栈1没满
    //将当前的top1位置附上值,再将top1往后移动一个
    shareSatck->data[shareSatck->top1++] = value;
}
//栈2的入栈操作函数
void ShareStack2Push(ShareStack *shareSatck,DataType value)
{
    if(shareSatck == NULL)
    {
        //非法输入
        return;
    }
    if(shareSatck->top1 == shareSatck->top2 || shareSatck->top2 == 0)
    {
        //栈2满了
        return;
    }
    //栈2没满
    //直接将top2往前移动一格在对其复制
    shareSatck->data[--shareSatck->top2] = value;
}
//栈1的出栈操作函数
void ShareStack1Pop(ShareStack *shareSatck)
{
    if(shareSatck == NULL)
    {
        //非法输入
        return;
    }
    if(shareSatck->top1 == 0 || shareSatck->top2 == 0)
    {
        //栈1是空栈
        printf("栈1是空栈\n");
        return;
    }
    //栈1内有元素,直接将top1往前移动一步
    shareSatck->top1--;
}
//栈2的出栈操作函数
void ShareStack2Pop(ShareStack *shareSatck)
{
    if(shareSatck == NULL)
    {
        //非法输入
        return;
    }
    if(shareSatck->top1 == max_size || shareSatck->top2 == max_size)
    {
        //栈2是空栈
        printf("栈2是空栈\n");
        return;
    }
    //栈2内有元素,直接将top2往后移动一步
    shareSatck->top2++;
}
//取栈1的栈顶元素操作函数,成功返回1,失败返回0
int ShareStack1Top(ShareStack *shareSatck,DataType *value)
{
    if(shareSatck == NULL)
    {
        //非法输入
        return 0;
    }
    if(shareSatck->top1 == 0 || shareSatck->top2 == 0)
    {
        //栈1是空栈
        return 0;
    }
    //栈1内有元素
    //栈1的在数组中的区间是[0,top1),所以当前top位置并没有值top1的前一个位置才是栈1的栈顶元素
    *value = shareSatck->data[shareSatck->top1-1]; 
    return 1;
}
//取栈2的栈顶元素操作函数,成功返回1,失败返回0
int ShareStack2Top(ShareStack *shareSatck,DataType *value)
{
    if(shareSatck == NULL)
    {
        //非法输入
        return 0;
    }
    if(shareSatck->top1 == max_size || shareSatck->top2 == max_size)
    {
        //栈2是空栈
        return 0;
    }
    //栈2内有元素
    //栈2在数组中的区间是[top2,max_size)
    //当前top2位置存放的就是栈2的栈顶元素
    *value = shareSatck->data[shareSatck->top2];
    return 1;
}
//打印栈1中的元素(便于观察测试结果思路不做解释)
void PrintStack1(ShareStack *shareSatck,const char *msg)
{
    printf("[%s]\n",msg);
    if(shareSatck == NULL)
    {
        //非法输入
        return;
    }
    if(shareSatck->top1 == 0 || shareSatck->top2 == 0)
    {
        //栈1是空栈
        return;
    }
    int i = 0;
    for(;i < shareSatck->top1;i++)
    {
        printf("%c ",shareSatck->data[i]);
    }
    printf("\n");
}
//打印栈2中的元素(便于观察测试结果思路不做解释)
void PrintStack2(ShareStack *shareSatck,const char *msg)
{
    printf("[%s]\n",msg);
    if(shareSatck == NULL)
    {
        //非法输入
        return;
    }
    if(shareSatck->top1 == max_size || shareSatck->top2 == max_size)
    {
        //栈2是空栈
        return;
    }
    int i = max_size-1;
    for(;i >= shareSatck->top2;i--)
    {
        printf("%c ",shareSatck->data[i]);
    }
    printf("\n");
}
//以下为测试函数
void TestShareStack()
{
    Test_Header;
    ShareStack shareSatck;

    //初始化栈1和栈2
    ShareStack1Init(&shareSatck);
    ShareStack2Init(&shareSatck);

    //栈1入栈函数测试
    ShareStack1Push(&shareSatck,'a');
    ShareStack1Push(&shareSatck,'b');
    ShareStack1Push(&shareSatck,'c');
    ShareStack1Push(&shareSatck,'d');
    PrintStack1(&shareSatck,"入栈1四个元素expected:a b c d");
    //栈1取栈顶元素函数测试1
    DataType top;
    int ret = ShareStack1Top(&shareSatck,&top);
    printf("expected ret = 1,actual ret = %d\n",ret);
    printf("expected top = d,actual ret = %c\n\n",top);
    //栈2入栈函数测试
    ShareStack2Push(&shareSatck,'z');
    ShareStack2Push(&shareSatck,'y');
    ShareStack2Push(&shareSatck,'x');
    ShareStack2Push(&shareSatck,'w');
    PrintStack2(&shareSatck,"入栈2四个元素expected:z y x w");
    //栈2取栈顶元素函数测试1
    ret = ShareStack2Top(&shareSatck,&top);
    printf("expected ret = 1,actual ret = %d\n",ret);
    printf("expected top = w,actual ret = %c\n\n",top);

    //栈1出栈函数测试
    ShareStack1Pop(&shareSatck);
    ShareStack1Pop(&shareSatck);
    PrintStack1(&shareSatck,"出栈1两个元素expected:a b");
    //栈1取栈顶元素函数测试2
    ret = ShareStack1Top(&shareSatck,&top);
    printf("expected ret = 1,actual ret = %d\n",ret);
    printf("expected top = b,actual ret = %c\n\n",top);
    //栈2出栈函数测试
    ShareStack2Pop(&shareSatck);
    ShareStack2Pop(&shareSatck);
    PrintStack2(&shareSatck,"出栈2两个元素expected:z y");
    //栈2取栈顶元素函数测试2
    ret = ShareStack2Top(&shareSatck,&top);
    printf("expected ret = 1,actual ret = %d\n",ret);
    printf("expected top = y,actual ret = %c\n\n",top);

    ShareStack1Pop(&shareSatck);                          
    ShareStack1Pop(&shareSatck);
    PrintStack1(&shareSatck,"将栈1中剩下的两个元素全部出栈");                             
    //栈1取栈顶元素函数测试3                              
    ret = ShareStack1Top(&shareSatck,&top);               
    printf("expected ret = 0,actual ret = %d\n\n",ret);     
    ShareStack2Pop(&shareSatck);
    ShareStack2Pop(&shareSatck);
    PrintStack2(&shareSatck,"将栈2中剩下的两个元素全部出栈");                             
    //栈2取栈顶元素函数测试3                              
    ret = ShareStack2Top(&shareSatck,&top);               
    printf("expected ret = 0,actual ret = %d\n\n",ret);

    //销毁栈1和栈2
    ShareStack1Push(&shareSatck,'a');
    ShareStack1Destroy(&shareSatck);
    ShareStack2Push(&shareSatck,'A');
    ShareStack2Destroy(&shareSatck);
    printf("[对销毁的栈操作,测试销毁函数]\n");
    ShareStack1Pop(&shareSatck);
    ShareStack2Pop(&shareSatck);
}
//以下为主函数调用测试函数
int main()
{
    TestShareStack();
    return 0;
}

以下为测试结果:

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_40927789/article/details/79979938

数据结构与算法——在一个数组中实现两个堆栈(C语言)

要求在一个数组中实现两个堆栈。函数接口定义:Stack CreateStack( int MaxSize ); bool Push( Stack S, ElementType X, int Tag ...
  • aaa946231
  • aaa946231
  • 2016-01-24 11:59:27
  • 873

【数据结构】栈面试题--一个数组实现两个栈

一个数组实现两个栈,有以下几种方法: 1.数组的奇数位置存储一个栈的元素,偶数位置存储另一个栈的元素; 2.两个栈分别从数组的中间向两头增长; 3.两个栈分别从数组的两头开始增长。 从...
  • peiyao456
  • peiyao456
  • 2016-10-03 20:17:37
  • 892

数据结构--一个数组实现两个栈

用一个数组实现两个栈,通常我们会想到以下几种方案: 1.奇偶栈,即就是将数组的偶数位置看作一个栈的存储空间,将奇数位置看作另一个栈的存储空间。 2.从中间分别向两边展开,即就是将数组的中间位置看作...
  • qq_29503203
  • qq_29503203
  • 2016-10-03 06:17:26
  • 1170

【数据结构】 一个数组实现两个栈【面试】

以前,我们实现一个栈,轻轻松松,无需考虑太多因素,即可实现。现在,要求在一个数组里实现两个栈,那么在数组里怎么实现栈呢?无非就是下标索引,方法也不局限一种,例如:用奇数下标作为栈s1的结构,用偶数作为...
  • wbq1480
  • wbq1480
  • 2016-05-26 12:26:10
  • 361

C语言实现栈(数组)

数组实现栈#include #include #define MAXSIZE 1000 #define element_type inttypedef struct { element_...
  • liukcqu
  • liukcqu
  • 2016-04-27 00:50:31
  • 675

C语言用两个栈实现一个队列的功能

  • 2009年10月22日 18:31
  • 1002B
  • 下载

c语言俩个栈实现一个队列

思路,现在设有俩个栈s1,s2。完成一个队列。     入队时,数据进入栈s1。出队时检查s2栈是否为空,为空则将s1出栈,出栈数据依次入栈s2。完成一个s1全部出栈后,s2出栈既是此时的出队操作。如...
  • u010916862
  • u010916862
  • 2017-04-19 20:34:45
  • 831

C语言实现栈(基于数组)

栈是一种操作受限的数据结构,只允许从一段操作,而且先进后出(FILO  first in last out)这里将栈的操作封装在C语言的头文件里实现栈的代码如下#include #define max...
  • weixin_36040034
  • weixin_36040034
  • 2016-11-26 13:51:04
  • 9941

两个栈实现队列功能C语言实现能运行!

两个栈实现队列功能 #include #include  typedef struct sq  {   char *ps;   int top;   int Maxsize;  }...
  • eqwewr
  • eqwewr
  • 2011-12-09 17:16:06
  • 1538
收藏助手
不良信息举报
您举报文章:通过一个数组实现两个栈(C语言)
举报原因:
原因补充:

(最多只允许输入30个字)