【原创】【自制系列】自制stack类型(泛型)
前言
自制类型的第三篇,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类型(泛型)的更多相关文章
- Shone.Math开源系列2 — 实数类型(含分数和无理数)的实现
Shone.Math开源系列2 实数类型(含分数和无理数)的实现 作者:Shone 声明:原创文章欢迎转载,但请注明出处,https://www.cnblogs.com/ShoneSharp. 摘要: ...
- [原创]如何在Parcelable中使用泛型
[原创]如何在Parcelable中使用泛型 实体类在实现Parcelable接口时,除了要实现它的几个方法之外,还另外要定义一个静态常量CREATOR,如下例所示: public static cl ...
- Java返回类型泛型的用法小结
Java返回类型泛型的用法小结 版权声明:本文为博主原创文章,未经博主允许不得转载. 关于Java泛型的基本用法就不多说了,主要是一个编译期的检查,也避免了我们代码中的强制转换,比较经典的用法有泛型D ...
- mybatis入门系列三之类型转换器
mybatis入门系列三之类型转换器 类型转换器介绍 mybatis作为一个ORM框架,要求java中的对象与数据库中的表记录应该对应 因此java类名-数据库表名,java类属性名-数据库表字段名, ...
- C# 基础知识系列- 10 反射和泛型(二)
0. 前言 这篇文章延续<C# 基础知识系列- 5 反射和泛型>,继续介绍C#在反射所开发的功能和做的努力.上一篇文章大概介绍了一下泛型和反射的一些基本内容,主要是通过获取对象的类型,然后 ...
- Java 集合系列 06 Stack详细介绍(源码解析)和使用示例
java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...
- 智能合约语言Solidity教程系列2 - 地址类型介绍
智能合约语言Solidity教程系列第二篇 - Solidity地址类型介绍. 写在前面 Solidity是以太坊智能合约编程语言,阅读本文前,你应该对以太坊.智能合约有所了解,如果你还不了解,建议你 ...
- 智能合约语言 Solidity 教程系列3 - 函数类型
Solidity 教程系列第三篇 - Solidity 函数类型介绍. 写在前面 Solidity 是以太坊智能合约编程语言,阅读本文前,你应该对以太坊.智能合约有所了解,如果你还不了解,建议你先看以 ...
- 【原创】3. MYSQL++ Query类型与SQL语句执行过程(非template与SSQLS版本)
我们可以通过使用mysqlpp:: Query来进行SQL语句的增删改查. 首先来看一下mysqlpp::Query的一些最简单的调用, conn.connect(mysqlpp::examples: ...
随机推荐
- 2020.12.3--vj个人赛补题
A Vasya studies music.He has learned lots of interesting stuff. For example, he knows that there are ...
- Install WSL
Install WSL Prerequisites You must be running Windows 10 version 2004 and higher (Build 19041 and hi ...
- [no_code]团队任务拆解Alpha
项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 团队任务拆解 我们在这个课程的目标是 远程协同工作,采用最新技术开发软件 这个作业在哪个具体方面帮 ...
- Prometheus监控Canal
Prometheus监控Canal 一.背景 二.实现步骤 1.修改prometheus.yml配置文件 2.启动prometheus 3.查看prometheus是否成功接入canal 4.cana ...
- 极简实用的Asp.NetCore框架再新增商城模块
概述 关于这个框架的背景,在前面我已经交代过了.不清楚的可以查看这个链接 1.极简实用的Asp.NetCore模块化框架决定免费开源了 2.极简实用的Asp.NetCore模块化框架新增CMS模块 算 ...
- Python课程笔记 (五)
今天主要学习图形用户界面,更多的还是要我们自己去实际操作,课仿佛上了一半就完了,分享一下课程(这里在SixthClass)的源码: https://gitee.com/wang_ming_er/pyt ...
- Obsidian中使用Calendar插件快捷建立日记、周记
Calendar插件 Calendar插件是我第一个安装使用的插件,插件可以帮助我们很便捷的记录每天的工作 插件效果图 插件下载 下载地址 插件安装 # Obsidian如何手动下载并安装插件-以看板 ...
- 从ACID到CAP及BASE
从ACID到CAP及BASE ACID 说到事务,肯定想到事务的ACID特性,即原子性(Atomicity).一致性(Consistency).隔离性(Isolation).持久性(Durabilit ...
- connect & send 在三次握手过程中的有趣问题
一.问题回顾 面试的时候被问到的问题,原问题是: 1:写一下socket网络编程服务端和客户端常用的函数. 2:如果服务端在listen之后没有accept,那客户端的connect会返回吗?为什么? ...
- mysqld:未被识别的服务(解决方法)
启动Mysql:sudo service mysqld start 执行该命令时,提示错误 mysqld:未被识别的服务,如图 解决办法如下: 1·.首先要找到 mysql.server 文件 命 ...