首页 > 其他分享 >共享栈:两栈共享空间

共享栈:两栈共享空间

时间:2024-09-02 12:25:03浏览次数:6  
标签:两栈 栈顶 top2 top1 数组 空间 共享 Stack SqShared

        现在这里插个链接,这是笔者之前写的一篇文章,讲的是基础版的栈,如果对栈不太熟悉可以先看看这一篇文章

引入

        上一篇文章我们学到了栈的顺序存储,这种方法只允许在栈顶针对元素进行操作,所以他并不存在像线性表一样在插入或删除操作时考虑移动元素的问题。但是他的缺陷也很明显,就是在开始我们就需要确定数组的空间的大小,万一不够用了,我们就需要使用编程手段来进行扩容(栈的链式存储),相当麻烦。但是相对的,如果有两个相同类型的栈,我们的操作空间就会更大一些。

        打个比方说,两个大学室友毕业同时去武汉工作。刚开始时,他们觉得住了这么就得集体宿舍,现在工作了,应该有一点属于自己的空间。所以他们决定租一间独住的一间房间,但是在他们仔细调研之后,发现最便宜的也得一千五,距离工作的地方还很远,实在是承受不起。最终他们还是合租了一间两居室,一共两千,各出一半。

        同样的道理,我们有两个相同类型的栈,我们为他们各自开辟了数组空间,可能是第一个栈的空间已经满了,但是第二个栈的空间还剩余很多,这肯定不合理,完全可以使用一个数组来存储两个栈。

因此,我们的做法如下图所示

        数组有两个端点,两个栈有两个栈底,所以我们使用一个栈的栈底放在数组的起始处,另一个栈底放在数组的另一端。这样的话,我们在增加元素的时候就从两端点向中间延伸。 

所以,我们的思路就是这样:

        两个栈在数组的两端,分别向中间去延伸。top1和top2是栈1和栈2的栈顶指针,所以我们也得知了判断栈满的条件就是S.top2 - S.top1 == 1。

结构代码

typedef struct
{
    ElementType data[MaxSize];
    int top1;// 指向栈1的栈顶
    int top2;// 指向栈2的栈顶
} SqShared_Stack;

初始化

void InitStack(SqShared_Stack &S)
{
    S.top1 = -1;
    S.top2 = MaxSize;
}

将两个栈的栈顶指针分别置于数组的两端

判空

bool isEmpty(SqShared_Stack S)
{
    if (S.top1 == -1 && S.top2 == MaxSize)
    {
        return true;
    }
    else
    {
        return false;
    }
}

        S.top1 == -1 && S.top2 == MaxSize 与我们初始化时的条件时一样的,所以我们认为他是空栈。

判满

bool isFull(SqShared_Stack S)
{
    if (S.top2 - S.top1 == 1)
    {
        return true;
    }
    else
    {
        return false;
    }
}

这个地方就和我们前面说的一样了, 两栈的栈顶重合了,我们就认为此时栈是满的。

入栈 

bool Push(SqShared_Stack &S, ElementType x, int flag)
//此处的flag是为了进行区别插入哪一个栈
{
    if (isFull(S))
    {
        cout << "The Shared_Stack is full!" << endl;
        return false;
    }
    else
    {
        if (flag == 1)
        {
            S.data[++S.top1] = x;
            return true;
        }
        else if (flag == 2)
        {
            S.data[--S.top2] = x;
            return true;
        }
        else
        {
            cout << "The flag is wrong!" << endl;
            return false;
        }
    }
}

出栈

bool Pop(SqShared_Stack &S, ElementType &x,int flag)
{
    if (isFull(S))
    {
        cout << "The Shared_Stack is empty!" << endl;
        return false;
    }
    else
    {
        if (flag == 1)
        {
            x = S.data[S.top1--];
            return true;
        }
        else if (flag == 2)
        {
            x=S.data[S.top2++];
            return true;
        }
        else
        {
            cout << "The flag is wrong!" << endl;
            return false;
        }
    }
}

获取栈顶元素

bool GetTop(SqShared_Stack S, ElementType &x, int flag)
{
    if (isEmpty(S))
    {
        cout << "The Shared_Stack is empty!" << endl;
        return false;
    }
    else
    {
        if (flag == 1)
        {
            x = S.data[S.top1];
            return true;
        }
        else if (flag == 2)
        {
            x = S.data[S.top2];
            return true;
        }
        else
        {
            cout << "The flag is wrong!" << endl;
            return false;
        }
    }
}

这些基础操作做完了之后就是我们的测试环节了。 

测试环节

SqShared_Stack S;
InitStack(S);
// 测试入栈
cout << "将元素推送到堆栈 1:" << endl;
for (int i = 1; i <= 5; i++)
{
    Push(S, i, 1);
}
Display(S);
cout << "将元素推入堆栈 2:" << endl;
for (int i = 10; i <= 15; i++)
{
    Push(S, i, 2);
}
Display(S);
// 测试获取栈顶元素
ElementType top;
GetTop(S, top, 1);
cout << "堆栈 1 的顶部元素: " << top << endl;
GetTop(S, top, 2);
cout << "堆栈 2 的顶部元素: " << top << endl;
// 测试出栈
ElementType popped;
cout << "从堆栈1中弹出元素:" << endl;
for (int i = 0; i < 3; i++)
{
    Pop(S, popped, 1);
    cout << "弹出 :" << popped << endl;
}
cout << "此时栈中的元素为:";
Display(S);
cout << "从堆栈2中弹出元素:" << endl;
for (int i = 0; i < 3; i++)
{
    Pop(S, popped, 2);
    cout << "弹出 :" << popped << endl;
}
cout << "此时栈中的元素为:";
Display(S);
// 测试判断栈是否为空或已满
cout << "堆栈是空的吗? " << (isEmpty(S) ? "是" : "不是") << endl;
cout << "堆栈是满的吗? " << (isFull(S) ? "是" : "不是") << endl;

 

标签:两栈,栈顶,top2,top1,数组,空间,共享,Stack,SqShared
From: https://blog.csdn.net/shouyeren153/article/details/141759930

相关文章

  • 书籍-《空间导航与跟踪:分析与算法》
    编辑:陈萍萍的公主@一点人工一点智能书籍:NavigationandTrackinginSpace:AnalysisandAlgorithms作者:SanatK.Biswas,AndrewG.Dempster出版:ArtechHouse01书籍介绍本书专注于人造空间物体的导航与跟踪,重点是对一系列广泛的空间任务进行动力学建模,包括:地球轨道卫星任务、发射......
  • 计算机毕业设计django+vue校园共享单车管理系统【开题+论文+程序】
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着校园规模的不断扩大和师生出行需求的日益增长,校园内的交通问题日益凸显。传统步行方式虽环保但效率低下,而私家车与电动自行车的无序停......
  • 命名空间在 C++ 中如何组织和管理代码?,c++中的命名空间是什么意思
    在C++编程中,命名空间(namespace)是组织和管理代码的重要工具。它为程序员提供了一种将代码按逻辑分组的方法,避免名称冲突,特别是在大型项目或使用多个库时显得尤为重要。命名空间可以看作是一个作用域,它包含了标识符(如变量、函数、类等)的集合。当我们在不同的模块中使用相同的标识符......
  • 多线程篇(ThreadLocal & 内存模型 & 伪共享(ThreadLocal ))(持续更新迭代)
    目录一、ThreadLocal1.前言2.简介3.与Synchronized的区别4.简单使用5.原理5.1.set5.2.get5.3.remove5.4.与Thread,ThreadLocalMap之间的关系5.常见使用场景场景一:存储用户Session场景二、数据库连接,处理数据库事务场景三、数据跨层传递(controller,servi......
  • 多线程篇(ThreadLocal & 内存模型 & 伪共享(内存可见性))(持续更新迭代)
    目录一、内存可见性问题(并发编程之美)二、Java内存模型(深入理解JVM第三版)1.简介2.硬件的效率与一致性3.Java内存模型3.1主内存与工作内存3.2内存间交互操作3.3对于volatile型变量的特殊规则3.4针对long和double型变量的特殊规则3.5原子性、可见性与有序性原......
  • ubuntu重新分配根目录存储空间-将根目录空间缩小腾出给别的位置
    我有个1t的固态,上面装了双系统,分了四分之一给windows,四分之三给ubuntu,现在出了黑神话悟空,我想玩一玩,黑神话悟空需要130g的存储,但是我的windows空间只剩50g,而且我又不想使用机械硬盘,毕竟太慢了。于是,我想把我的ubuntu再分出四分之一给windows,相当于两个系统各占一半的空间。经过......
  • IO进程day06(进程间通信、信号、共享内存)
    目录【1】进程间通信IPC1》进程间通信方式2》无名管道1>特点2>函数接口3>注意事项练习:父子进程实现通信,父进程循环从终端输入数据,子进程循环打印数据,当输入quit结束。3》有名管道 1>特点2>函数接口3>注意事项 练习:通过两个进程实现cp功能 4>有名管......
  • 【Internet Protocol】ip介绍,如何组局域网实现远程桌面和文件共享
    @目录1.何为“上网”1.1定义1.2为什么连了WiFi就能上网了?2.ip2.1什么是ip2.2为什么区分广域网和局域网,ip的唯一性2.3如何查看设备的ip2.4什么叫"ping"2.5区分是否两个ip是否在同一局域网2.5.1最稳妥的方式:ip&mask2.5.2最方便的方式:ping2.6ipv4与ipv6的区别3.远程桌面控......
  • CUDA教程之 10 掌握 CUDA 矩阵乘法:共享内存、Tile 内存合并和 Bank 冲突简介(教程含源
    介绍在使用CUDA进行GPU编程的世界中,优化性能是关键。实现此目标的最强大技术之一是使用共享内存。本博客将引导您完成使用共享内存执行矩阵乘法的CUDA程序,特别关注理解分块内存合并和存储体冲突。在本文结束时,您将牢固掌握共享内存如何显著加快您的计算速度以及如何......
  • day10(IO进程)进程间的通信---共享内存
    目录1.特点2.步骤3.函数接口4.命令1.特点1)共享内存是一种最为高效的进程间通信方式,进程可以直接读写内存,而不需要任何数据的拷贝。2)为了在多个进程间交换信息,内核专门留出了一块内存区,可以由需要访问的进程将其映射到自己的私有地址空间。进程就可以直接读......