前言

自制类型的第三篇,stack类型。stack是指栈,其实我个人认为stack是最好写的类型,没有之一。关于queue类型需要涉及到循环队列避免浪费内存,但是stack的插入删除都是对于栈顶而言,比较好写。

自制类型的主要目的,是为了练习数据结构,提高写代码的能力。

常见函数

s.empty() 判断栈s是否为空

s.size() 返回栈s的大小

s.push(a) 把a推入栈

s.pop() 弹出栈顶元素

s.top() 返回栈顶元素

泛型

我们在使用标准库的stack,是这样写的:

stack<int> stk;

使用尖括号指定类型,就是泛型的一种。如果把int改为char,甚至是结构体等,都可以。

最简单的例子:

#include<iostream>
#include<vector>
using namespace std;
int main(){
int a=5,b=10;cout<<max(a,b);
float c=3.14,d=9.99;cout<<max(c,d);
char e='x',f='*';cout<<max(e,f);
}

这里,max函数即可以处理int,又可以处理float,char类型的最大值。这就是泛型。max函数无论针对哪一个类型,操作都是相同的。因此,我们使用通用类型,让函数不关注类型只关注具体的操作。

有人会问,其实使用函数重载不就能完成了吗?但是,函数重载要重复写好几次,不方便。

泛型的函数,可以使用template关键字写:

#include<iostream>
#include<vector>
using namespace std;
template<typename T>
T MAX(T a,T b){
if(a>b)return a;
else return b;
}
int main(){
int a=5,b=10;cout<<MAX(a,b);
float c=3.14,d=9.99;cout<<MAX(c,d);
char e='x',f='*';cout<<MAX(e,f);
}

template表示定义一个叫做T的类型,这个类型是一个通用类型。这个语句告诉编译器,要开始泛型编程,其中T是要使用的泛型类型。

执行的时候,编译器会自动根据参数的类型,把T转换为int,float等类型,进行计算。

注意,泛型的函数不会进行自动类型转换,例如cout<<MAX('a',100);这个语句,如果使用的是泛型类型,会编译错误,但是使用普通类型不会报错,因为普通类型的函数会进行自动类型转换。

泛型类的写法:

template<typename T>
class Vector{
T *numbers; };

(转自我之前写过的《自制vector类型》)

这样,就可以像标准库一样定义了。

在类的函数中,对于参数和部分类变量,也需要把类型指定为T,在malloc和realloc的强制转型中也是T*。

大体写法

class Stack{
private:
T *Data;
int nData;
public:
Stack(){
Data=nullptr;
nData=0;
}
bool empty(){
if(nData==0)return true;
else return false;
}
int size(){
return nData;
}
void push(T a){
nData++;
if(Data==nullptr)Data=(T*)malloc(sizeof(T));
Data=(T*)realloc(Data,nData*sizeof(T));
Data[nData-1]=a;
}
void pop(){
if(nData==0)return;
nData--;
Data=(T*)realloc(Data,nData*sizeof(T));
}
T top(){
return Data[nData-1];
}
};

构造函数的写法

将Data,nData初始化,变量的含义很简单,不再多说。

empty

判断栈的大小即可。如果大小为0,表示为空栈。

size

返回nData。

push

重头戏

  void push(T a){
nData++;
if(Data==nullptr)Data=(T*)malloc(sizeof(T));
Data=(T*)realloc(Data,nData*sizeof(T));
Data[nData-1]=a;
}

首先,把栈的大小加上1。然后,如果为空指针,就使用malloc分配(原来什么都没有),否则使用realloc分配。动态分配内存,可以节约内存空间。最后,把push的数值放入栈顶。

pop

pop的操作也很简单。

  void pop(){
if(nData==0)return;
nData--;
Data=(T*)realloc(Data,nData*sizeof(T));
}

pop操作需要对nData做特判,大小为零则直接退出,不然在分配时会出错。

如果nData=0,那么realloc的参数为0,相当于使用free(Data)。

top

返回栈顶元素Data[nData-1]。

【原创】【自制系列】自制stack类型(泛型)的更多相关文章

  1. Shone.Math开源系列2 — 实数类型(含分数和无理数)的实现

    Shone.Math开源系列2 实数类型(含分数和无理数)的实现 作者:Shone 声明:原创文章欢迎转载,但请注明出处,https://www.cnblogs.com/ShoneSharp. 摘要: ...

  2. [原创]如何在Parcelable中使用泛型

    [原创]如何在Parcelable中使用泛型 实体类在实现Parcelable接口时,除了要实现它的几个方法之外,还另外要定义一个静态常量CREATOR,如下例所示: public static cl ...

  3. Java返回类型泛型的用法小结

    Java返回类型泛型的用法小结 版权声明:本文为博主原创文章,未经博主允许不得转载. 关于Java泛型的基本用法就不多说了,主要是一个编译期的检查,也避免了我们代码中的强制转换,比较经典的用法有泛型D ...

  4. mybatis入门系列三之类型转换器

    mybatis入门系列三之类型转换器 类型转换器介绍 mybatis作为一个ORM框架,要求java中的对象与数据库中的表记录应该对应 因此java类名-数据库表名,java类属性名-数据库表字段名, ...

  5. C# 基础知识系列- 10 反射和泛型(二)

    0. 前言 这篇文章延续<C# 基础知识系列- 5 反射和泛型>,继续介绍C#在反射所开发的功能和做的努力.上一篇文章大概介绍了一下泛型和反射的一些基本内容,主要是通过获取对象的类型,然后 ...

  6. Java 集合系列 06 Stack详细介绍(源码解析)和使用示例

    java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...

  7. 智能合约语言Solidity教程系列2 - 地址类型介绍

    智能合约语言Solidity教程系列第二篇 - Solidity地址类型介绍. 写在前面 Solidity是以太坊智能合约编程语言,阅读本文前,你应该对以太坊.智能合约有所了解,如果你还不了解,建议你 ...

  8. 智能合约语言 Solidity 教程系列3 - 函数类型

    Solidity 教程系列第三篇 - Solidity 函数类型介绍. 写在前面 Solidity 是以太坊智能合约编程语言,阅读本文前,你应该对以太坊.智能合约有所了解,如果你还不了解,建议你先看以 ...

  9. 【原创】3. MYSQL++ Query类型与SQL语句执行过程(非template与SSQLS版本)

    我们可以通过使用mysqlpp:: Query来进行SQL语句的增删改查. 首先来看一下mysqlpp::Query的一些最简单的调用, conn.connect(mysqlpp::examples: ...

随机推荐

  1. 2020.12.3--vj个人赛补题

    A Vasya studies music.He has learned lots of interesting stuff. For example, he knows that there are ...

  2. Install WSL

    Install WSL Prerequisites You must be running Windows 10 version 2004 and higher (Build 19041 and hi ...

  3. [no_code]团队任务拆解Alpha

    项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 团队任务拆解 我们在这个课程的目标是 远程协同工作,采用最新技术开发软件 这个作业在哪个具体方面帮 ...

  4. Prometheus监控Canal

    Prometheus监控Canal 一.背景 二.实现步骤 1.修改prometheus.yml配置文件 2.启动prometheus 3.查看prometheus是否成功接入canal 4.cana ...

  5. 极简实用的Asp.NetCore框架再新增商城模块

    概述 关于这个框架的背景,在前面我已经交代过了.不清楚的可以查看这个链接 1.极简实用的Asp.NetCore模块化框架决定免费开源了 2.极简实用的Asp.NetCore模块化框架新增CMS模块 算 ...

  6. Python课程笔记 (五)

    今天主要学习图形用户界面,更多的还是要我们自己去实际操作,课仿佛上了一半就完了,分享一下课程(这里在SixthClass)的源码: https://gitee.com/wang_ming_er/pyt ...

  7. Obsidian中使用Calendar插件快捷建立日记、周记

    Calendar插件 Calendar插件是我第一个安装使用的插件,插件可以帮助我们很便捷的记录每天的工作 插件效果图 插件下载 下载地址 插件安装 # Obsidian如何手动下载并安装插件-以看板 ...

  8. 从ACID到CAP及BASE

    从ACID到CAP及BASE ACID 说到事务,肯定想到事务的ACID特性,即原子性(Atomicity).一致性(Consistency).隔离性(Isolation).持久性(Durabilit ...

  9. connect & send 在三次握手过程中的有趣问题

    一.问题回顾 面试的时候被问到的问题,原问题是: 1:写一下socket网络编程服务端和客户端常用的函数. 2:如果服务端在listen之后没有accept,那客户端的connect会返回吗?为什么? ...

  10. mysqld:未被识别的服务(解决方法)

    启动Mysql:sudo service mysqld start 执行该命令时,提示错误   mysqld:未被识别的服务,如图 解决办法如下: 1·.首先要找到 mysql.server 文件 命 ...