返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++栈的数组实现代码
  • 182
分享到

C++栈的数组实现代码

2024-04-02 19:04:59 182人浏览 八月长安
摘要

栈的抽象数据结构。栈的成员函数需要包括这几个基本的函数:initializeStack(),isEmptyStack(),isFullStack,push(),pop(),top()

栈的抽象数据结构。栈的成员函数需要包括这几个基本的函数:initializeStack(),isEmptyStack(),isFullStack,push(),pop(),top()

其功能如下:

  • initializeStack():初始化栈
  • isEmptyStack():判断栈是否为空
  • isFullStack():判断栈是否已满
  • push():将一个元素压入栈中
  • pop():删除栈顶元素
  • top():获得栈顶元素

c++中用抽象类作为基类实现ADT如下:

template<class Type>
    class stackADT
    {
        virtual void initializeStack()=0;//virtual和=0表明都是纯虚函数,抽象类中只能声明纯虚函数,不能定义
        virtual bool isEmptyStack() const=0;//const放在函数后面,表明该函数是常成员函数,在函数执行过程中不能改变函数内部变量的值
        virtual bool isFullStack() const=0;
        virtual void push(const Type&)=0;//引用常量,该函数不会自动对输入进行赋值,同时在函数内的操作也不能改变输入的值
        virtual void pop()=0;
        virtual Type top() const=0;//这里也采用常成员函数,因为函数不会对变量进行修改,只是返回变量
    };

​ 补充说明:

  • 抽象类:一个类中只要有一个纯虚函数,那么该类就是抽象类,抽象类通常作为基类,纯虚函数在抽象类中只能声明不能定义。
  • 常成员函数:什么时候才使用常成员函数?一般在如果该函数在执行过程中不会有改变变量值的操作,就会把该函数定义为常成员函数。
  • 常引用:常引用一般用于函数输入,或者函数返回值。如函数输入是常引用类型,那么说明该函数只会用到引用的值,而不会改变引用变量的值,同时可能引用变量的类型可能很大比较占内存,所以用引用可以避免输入参数的复制,从而节约了空间;若函数返回值为常引用类型,那么有两个原因,首先const表示返回值不能被修改(注意和常成员函数做区分),引用则表示函数返回时不会对返回变量进行拷贝,从而不会触发拷贝函数,因此经常被用于运算符重载,但是要注意返回值不能是函数局部变量,因为局部变量在函数结束后会被释放,从而引用了不合法的内存,会报错,像如果是运算符重载返回的基本是this指向的对象,这对于函数来说则是全局的,所以是没问题的,一般如果返回值是对象,且要避免拷贝,那么就把返回值类型设置为常引用。总之引用作为输入参数或者返回值时就是为了避免产生副本,而const则是为了保证变量不被修改。
  • 栈的动态数组实现

​ 直接继承抽象类,不管是动态数组实现还是链表实现,抽象类的那几个成员函数都是需要的,但是函数实现的内容不一样

​ 这就体现了多态了。

​ 下面是派生栈类的定义:

template <class Type>
    class stackType:public stackADT<Type> //一定要记住每次用到模板类时不要忘记后面的<Type>
    {
        public:
        stackType(int stackSize=100);//注意这里用到了参数缺省构造函数中的参数缺省必须在声明函数时给出默认值而不能在定义函数时给出默认值;stackType作为函数名,因此后面不要加<Type>
        stackType(const stackType<Type>&); //拷贝构造函数
        ~stackType();
        const stackType<Type>& operator=(const stackType<Type>&);//重载赋值运算符
        void initializeStack();
        bool isEmptyStack()const;
        bool isFullStack()const;
        void push(const Type&);
        void pop();
        Type top()const;
        private:
        Type* list;//指向栈的首地址
        int maxStackSize;//栈的最大容量
        int stackTop;//栈顶元素的位置(从1开始)
        void copyStack(const stackType<Type>&);//执行深拷贝过程
    };//注意不要忘记分号

​ 成员函数的实现如下:

​ initializeStack():

template<class Type>//在类外定义函数必须使用template,并且每定义一个函数就要写一次
void stackType<Type>::initializeStack()  //命名空间也不要忘记::,因为命名空间的名字是模板类,所以后面要有<Type>
{
    stackTop=0;//不需要把元素全部置零,只需要把栈顶元素的索引变成0即可
}

​ isEmptyStack():

template<class Type>
bool stackType<Type>::isEmptyStack()const
{
    return !stackTop;//可以认为stackTop表示栈中目前元素的个数,为0则表示空栈
}

​ isFullStack():

template<class Type>
bool stackType<Type>::isFullStack()const
{
    return stackTop==maxStackSize;
}

​ push():

template<class Type>
void stackType<Type>::pop()
{
    if(!isEmptyStack())
        stackTop--;
    else
        cout<<"The stack is empty,cannot add to an item"<<endl;
}

​ pop():

template<class Type>
void stackType<Type>::pop()
{
    if(!isEmptyStack())
        stackTop--;
    else
        cout<<"The stack is empty,cannot add to an item"<<endl;
}

​ top():

template<class Type>
Type stackType<Type>::top()const
{
    assert(!isEmptyStack());//如果栈为空那么必须终止程序,reuturn 返回的会是乱码,push和pop不需要这个操作是因为他们没有返回值,所以如果不满足执行的条件只需要在终端上显示出现异常就行。
    return list[stackTop-1];
}

​copyStack():

template<class Type>
void stackType<Type>::copyStack(const stackType<Type>& otherStack)
{
    delete [] list;   //释放当前栈的内存,注意如果delete的是一个空指针,那么delete不会执行,因此就不需要判断是否为空指针
    stackTop=otherStack.stackTop;
    maxStackSize=otherStack.maxStackSize;
    list=new Type[maxStackSize];  //
    for(int i=0;i<stackTop;i++)
        list[i]=otherStack.list[i];
}

​stackType():构造函数

template<class Type>
stackType<Type>::stackType(int stackSize)
{
    if(stackSize<=0)
    {
        cout<<"The size must be positive"<<endl;
        cout<<"creating an array of size 100"<<endl;
        maxStackSize=100;
    }
    else
    {
        maxStackSize=stackSize;
    }
    stackTop=0;
    list=new Type[maxStackSize];
}

​stackType():拷贝构造函数

template<class Type>
stackType<Type>::stackType(const stackType<Type>& otherStack)
{
    list=nullptr;       //这里list必须置为空,因为在这个程序中,赋值栈的赋值触发的是运算符重载,而拷贝构造函数只有在作为函数输入参数时或者返回参数时才会被触发,同时由于拷贝构造函数是构造函数重载,所以在触发拷贝构造函数前并不会触发构造函数,也意味着并没有给list分配内存,那么list就是一个野指针,如果不置为空那么调用copyStack()时,由于copyStack中第一条语句就是delete []list;删除没有分配内存的野指针就会报错,所以list置为空是必须的
    copyStack(otherStack);
}

operator=():赋值运算符重载

template<class Type>
const stackType<Type>& stackType<Type>::operator=(const stackType<Type>& otherStack)
{
    if(this!=&otherStack) //避免自我复制
    copyStack(otherStack);
    return *this;
}

​~stackType():析构函数

template<class Type>
stackType<Type>::~stackType()
{
    delete [] list;
}

​文件构成有两种方式

stackADT单独一个头文件,stackADT.h,stackType类在头文件stackArr.h中定义,在.cpp文件中实现。

stackArr.h

#include "stackADT.h"
//类的定义放在这里

stacArr.cpp

#include<iOStream>
#include<cassert>
#include "stackArr.h"
using namespace std;
//类的实现放在这里

main.cpp

#include "stackArr.cpp" //这里不能include "stackArr.h",因为这里是模板类,模板类需要编译两次,
int main()
{
    //主函数的内容
    return 0;
}

2.把stackArr类的定义和实现都放进一个头文件stackArr.h

#ifndef H_StackType
#define H_StackType
#include<iostream>
#include<cassert>
#include "stackADT"
using namespace std;
//类的定义如下
//此处写类的成员函数的实现
#endif

总结:使用模板实现栈的一些要点

首先栈最重要的特征就是先入后出,有一端相当于是封闭的,另外栈的一个重要标识就是栈顶,如果用数组实现栈,那么就通过栈顶元素的索引+1(因为索引从0开始)来表示栈顶。

2.把对象复制过程进行了分离,这里用copyStack函数实现了对象成员变量的复制,由于成员变量中有指针,而且指针指向的是动态内存所以必须进行深拷贝,而在拷贝构造函数中直接调用copyStack函数即可,同时这里将赋值运算符进行了重载,那么对于语句a=b,调用的就不是拷贝构造函数了,而是调用运算符重载,只有在作为函数输入或者返回参数时生成对象副本次才会调用拷贝构造函数,还有析构函数要把内存释放,否则会导致内存泄漏。

3.注意push,pop,top的异常判断,这也是初学最容易忽视的点,不要嫌麻烦,对于会导致程序出错的输入要终止程序,像本程序中top函数是有返回值的所以如果是空栈的话返回的就是乱码所以遇到空栈用了assert函数退出程序,像如果只是输入不合法,像push函数,因为是先判断的栈是否已经满了,而且没有返回值,假如栈已满,我们不进行压栈操作就行了,只需要在终端打印错误信息就行,因此就没必要终止程序。

4.特别注意类模板的定义和实现,对于模板类而言最好还是把定义和实现的代码放在同一个头文件,同样采取类内声明,类外定义的方法。对非模板类而言,类的定义和实现通常不在同一个头文件,一般就是在头文件中定义类,然后在同名的.cpp文件中实现成员函数。
[[栈的链表实现]]

到此这篇关于C++栈的数组实现的文章就介绍到这了,更多相关C++栈的数组实现内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C++栈的数组实现代码

本文链接: https://lsjlt.com/news/148080.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C++栈的数组实现代码
    栈的抽象数据结构。栈的成员函数需要包括这几个基本的函数:initializeStack(),isEmptyStack(),isFullStack,push(),pop(),top()...
    99+
    2024-04-02
  • C++链栈的实现代码怎么写
    这篇文章主要讲解了“C++链栈的实现代码怎么写”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++链栈的实现代码怎么写”吧!链栈简述链栈从概念上看是链表和栈的结合,含有栈先进后出的特性,也具...
    99+
    2023-07-02
  • C语言实现栈的示例代码
    目录一、了解栈的结构特点二、具体实现补充 栈的用处一、了解栈的结构特点 栈是一种特殊的线性表,只允许从一端进出数据,称为后进先出,先进后出。 压栈:栈的插入操作叫做进栈/压...
    99+
    2024-04-02
  • C语言 栈与数组的实现详解
    目录栈的实现栈的定义数组实现静态栈动态栈链栈栈的实现 首先我们思考一个问题,什么是栈? 栈是数据结构的一种,栈在我们日常编码中遇到的非常多,很多人对栈的接触可能仅仅局限在 递归使用的...
    99+
    2024-04-02
  • C语言超详细讲解栈的实现及代码
    目录前言栈的概念栈的结构栈的实现创建栈结构初始化栈销毁栈入栈出栈获取栈顶元素获取栈中有效元素个数检测栈是否为空总代码Stack.h 文件Stack.c 文件Test.c 文件前言 栈...
    99+
    2024-04-02
  • TypeScript数组实现栈与对象实现栈的区别详解
    目录前言数组实现栈实现思路实现代码编写测试代码对象实现栈实现代码编写测试代码二者的区别十进制转二进制前言 栈作为一种数据结构,它可以应用在很多地方,当你需要经常获取刚存放进去的数据时...
    99+
    2024-04-02
  • Java栈之链式栈存储结构的实现代码
    Java栈之链式栈存储结构实现一、链栈采用单链表来保存栈中所有元素,这种链式结构的栈称为链栈。二、栈的链式存储结构实现package com.ietree.basic.datastructure.stack;public class Lin...
    99+
    2023-05-31
    java 存储
  • java中栈的数组和链表实现
    栈的介绍栈,是一种先进后出(FILO)的线性数据结构,主要操作为入栈和出栈。栈底:最早进入的元素存放的位置。栈顶:最后进入元素存放的位置(有些栈中将栈顶表示为栈顶元素的下一位置)。免费在线学习视频推荐:java视频栈的数组的实现示例如下:p...
    99+
    2014-09-11
    java教程 java 数组 链表 实现
  • Python数据结构之栈、队列的实现代码分享
    1. 栈 栈(stack)又名堆栈,它是一种运算受限的线性表。其限制是仅允许在表的一端进行插入和删除运算。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放...
    99+
    2022-06-04
    数据结构 队列 代码
  • c++实现简单随机数的代码
    c++简单随机数 #include<iostream> #include<ctime> #include<cstdlib> using na...
    99+
    2024-04-02
  • C++实现栈与分析栈的知识点
    目录一、栈的概念二、栈的基本组成和操作三、栈元素的存储方式四、C++实现静态栈(1)栈类的设计(1)isEmpty()判断是否为空(2)isFull()判断是否已满(3)push()...
    99+
    2024-04-02
  • C++详解链栈的实现
    目录链栈简述示例代码开发环境运行结果注意链栈简述 链栈从概念上看是链表和栈的结合,含有栈先进后出的特性,也具有链表的动态增加节点的特性,这里相当于在链表的基础上增加只能从一端操作,且...
    99+
    2024-04-02
  • golang实现数组分割的示例代码
    需求:给定一个数组和一个正整数,要求把数组分割成多个正整数大小的数组,如果不够分,则最后一个数组分到剩余的所有元素。 示例1: 数组:[1, 2, 3, 4, 5, 6, 7,...
    99+
    2024-04-02
  • c++数组排序的5种方法实例代码
    目录方法一:冒泡排序方法二:sort函数排序方法三:用交换函数swap排序方法四:快速排序方法五:归并排序总结方法一:冒泡排序 比较相邻的元素。如果第一个比第二个大,就交换他们两个。...
    99+
    2023-01-11
    c++数组排序函数 C++数组排序有几种 c++数组的排序
  • C++ 实现一个复数类的实例代码
    要求 实现⼀个复数类 Complex 。 Complex 类包括两个 double 类型的成员 real 和 image ,分别表示复数的实部和虚部。 对 Comple...
    99+
    2024-04-02
  • C++代码调用C#代码的过程怎么实现
    这篇文章主要讲解了“C++代码调用C#代码的过程怎么实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++代码调用C#代码的过程怎么实现”吧!首先建立一个C#工程Class Library...
    99+
    2023-06-17
  • Python 数据结构之堆栈实例代码
    Python 堆栈 堆栈是一个后进先出(LIFO)的数据结构. 堆栈这个数据结构可以用于处理大部分具有后进先出的特性的程序流 . 在堆栈中, push 和 pop 是常用术语: push: 意思是把...
    99+
    2022-06-04
    堆栈 数据结构 实例
  • java整数与byte数组的转换实现代码
    java整数与byte数组的转换实现代码           这里对java中整数与byte数组的转换进行了实现,平时的项目中很少...
    99+
    2023-05-31
    java 整数 byte数组
  • C++实现Matlab的zp2tf函数的示例代码
    目录1. matlab 的 zp2tf 函数的作用2. matlab 的 zp2tf 函数的使用方法3. C++实现3.1 complex.h 文件3.2 zp2tf.h 文件4. ...
    99+
    2023-05-16
    C++实现Matlab zp2tf函数 C++实现Matlab函数 C++ Matlab zp2tf函数 C++ Matlab
  • Python代码实现列表分组计数
    目录1. count_by2. 使用字典推导式3. 使用collections.defaultdict简化代码 本篇阅读的代码片段来自于30-seconds-of-python。 1...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作