典型数据结构的模板实现
栈和数组
- 1.使用类模板实现数组结构
- 定长数组
- 可变数组
- 2.使用类模板实现栈结构
在我们初步了解编写模板类后,应当做一下代码练习。这节我们就做一个编写代码的补充,方便大家继续学习模板类的嵌套。作为新手而言,建议大家先写一个具体类,调试好后再去修改成模板类,因为调试模板类会相对复杂。
1.使用类模板实现数组结构
数组是我们常用的一种数据类型,我们今天的内容就先从编写一个数组类模板开始。数组有定长数组和边长数组的区别,我们只来实现它们的部分功能。
定长数组
首先我们先学习编写一个int类型的定长数组数组类。我们只实现查看和改写数组的元素即可。这个过程中涉及到重载[]运算符:
#define Arraysize 10
class Array
{private:int items[Arraysize]; // 声明一个数组,这里的[]不是运算符public:int sign=0; // 用于标记重载的[]运算符使用了几次Array(){memset(items,0,sizeof(items));} // 使用memset函数初始化数组,需要知道首地址、初始化值、数组元素类型所占空间int& operator[] (int ii) // 重载[]运算符,返回值类型为int的引用{this->sign++; // this指针类似于python中的self,他默认标记类地址,可以查找类内容return *(items+ii);}const int& operator[] (int ii) // 如果是const修饰的数组,上面的函数将不会被调用const{return *(items+ii);}
};
这段代码里我偷偷用了一些没有讲到的函数和知识点。包括重载运算符,初始化函数和类的this指针。当然这段代码当然没有使用this指针的必要,this->sign++直接写成sign++效果也是一样的。
写好之后我们来测试一下:
int main()
{Array a;a[0]=1;a[1]=2;a[2]=3;a[3]=4;for(int i=0;i<5;i++){cout<<a[i]<<" ";}cout<<"\n"<<a.sign<<endl;
}
// 输出为:1 2 3 4 0
// 9
接下来我们把它改成函数模板的样子。因为函数模板可以定义已知类型,所以我们也可以这样写:
template <class T, int Arraysize=10>
class Array
{private:T items[Arraysize]; // 声明一个数组,这里的[]不是运算符public:int sign=0; // 用于标记重载的[]运算符使用了几次Array(){memset(items,0,sizeof(items));} // 使用memset函数初始化数组,需要知道首地址、初始化值、数组元素类型所占空间T& operator[] (int ii) // 重载[]运算符,返回值类型为T的引用{this->sign++; // this指针类似于python中的self,他默认标记类地址,可以查找类内容return *(items+ii);}const T& operator[] (int ii) // 如果是const修饰的数组,上面的函数将不会被调用const{return *(items+ii);}
};
再来测试一下:
int main()
{// Array<double,5> a;Array<double> a;a[0]=1;a[1]=2;a[2]=3;a[3]=4;for(int i=0;i<10;i++){cout<<a[i]<<" ";}cout<<"\n"<<a.sign<<endl;
}
// 输出为:1 2 3 4 0 0 0 0 0 0
// 14
注意:非通用类型参数通常是整数型(但不绝对),这个值在函数模板实例化之后是不可以修改的。定长数组功能实现起来并不难,接下来我们试试变长数组。
可变数组
这个功能并不难实现,我们仅对上述代码实现少量改动,即当访问下标超过数组最大长度时,我们要重新分配更大的内存存储这个数组:
template <class T>
class Vector
{private:int len;T *items; // 声明一个指针变量,用于接收动态数组public:Vector(int size=5) // C++的参数也可以像python一样使用默认参数{len=size;items=new T[len];} ~Vector() // 释放动态分配的内存{delete[] items;items=nullptr;}void resize(int size) // 当数组超出容量时会重新分配内存{T* temp;if (size>len){temp=new T[size];} // 分配更大的内存else return;for(int i=0;i<len;i++) // 将旧数组拷贝到新数组{temp[i]=items[i];}delete[] items; // 释放原数组items=temp; // 指向新数组len=size; // 更新数组大小}int size()const{ // 返回数组长度return len;}T& operator[] (int ii) // 重载[]运算符,返回值类型为T的引用{if (ii>=len){this->resize(len+5); // 分配多五个空间的新数组}return *(items+ii);}const T& operator[] (int ii) // 如果是const修饰的数组,上面的函数将不会被调用const{return *(items+ii);}
};
这样就完成了,大家可以自行尝试一下。
2.使用类模板实现栈结构
栈是一种先进后出的数据结构,我们主要通过类模板实现它的入栈、出栈、判空、判满功能。首先我们编写一个函数实现int类型的栈:
class Stack
{private:int *items; // 由数组结构定义的栈int stacksize; // 栈含元素数量int top; // 栈顶指针,并非指针类型,而是类似于数组下标public:// 初始化栈Stack(int size):stacksize(size),top(0){items=new int[stacksize];}// 析构函数,删除动态空间~Stack(){delete[] items;items=nullptr;}// 判空函数,即判断栈顶指针是否为0bool isempty() const // 不允许在函数内修改任何变量值{return top==0;}// 判满函数bool isfull() const{return top==stacksize;}// 压栈函数bool push(const int& item){if(!isfull()){items[top++]=item;return true;}else return false;}// 出栈函数bool pop(int &item){if(!isempty()){item=items[--top];return true;}else return false;}
};
这样我们就实现了定义一个功能简单的处理类型int栈。下面我们先来测试一下各个功能是否正常,然后再看看如何把这个具体类制作成类模板:
int main()
{Stack ss(5);cout<<ss.isempty()<<" "<<ss.isfull()<<endl;ss.push(1);ss.push(2);ss.push(3);ss.push(4);ss.push(5);cout<<ss.isempty()<<" "<<ss.isfull()<<endl;int item;while(ss.pop(item)){cout<<item<<" ";}
}
// 输出为:1 0
// 0 1
// 5 4 3 2 1
这样看起来,我们的功能实现的还不错。接下来我们把它定义成可以处理不同数据类型的栈类。我们可以使用
typedef *** Mydata
在星号处填入想要处理的类型,然后将与items有关的代码全都改成Mydata(或Mydata*)类。这样做的缺点是我们经常要手动去调整类所处理的数据类型。
在有了类模板之后,我们就可以更方便的解决这些问题了:
template<class T>
class Stack
{private:T *items; // 由数组结构定义的栈int stacksize; // 栈含元素数量int top; // 栈顶指针,并非指针类型,而是类似于数组下标public:// 初始化栈Stack(int size):stacksize(size),top(0){items=new T[stacksize];}// 判空和判满不需要改动// 压栈函数bool push(const T& item){if(!isfull()){items[top++]=item;return true;}else return false;}// 出栈函数bool pop(T &item){if(!isempty()){item=items[--top];return true;}else return false;}
这样我们就成功的做出了一个模板类实现栈的部分功能了。
相关文章:
典型数据结构的模板实现
栈和数组 1.使用类模板实现数组结构定长数组可变数组 2.使用类模板实现栈结构 在我们初步了解编写模板类后,应当做一下代码练习。这节我们就做一个编写代码的补充,方便大家继续学习模板类的嵌套。作为新手而言,建议大家先写一个具体类&#x…...
Visual Studio 2022中创建的C++项目无法使用万能头<bits/stdc++.h>解决方案
目录 发现问题 解决办法 第一步 第二步 第三步 第四步 最后一步 问题解决 发现问题 如果大家也遇到下面这种问题,可能是没有include文件夹中没有bits/stdc.h 解决办法 第一步 打开一个C项目,鼠标移动至头文件上右击,选择转到文档或…...
webpack配置
一、很多基础方面的配置被vuecli所集成一般项目都是使用vuecli,不会真正的去从0-1进行webpack配置: 1、vuecli中的webpack基础配置: (1)入口文件默认在src/main;输出在dist; (2)集成了大量的插件和加载器:babel-loader 处理 JavaScript 文件、使用 css-loader 和 style-load…...
1 月 Web3 游戏行业概览:市场实现空前增长
作者:lesleyfootprint.network 今年一月,区块链游戏领域迎来了爆发式增长,活跃用户的数量大幅提升。 区块链游戏不断融合 AI 技术,旨在提升玩家体验并扩大其服务范围,公链与游戏的兼容性问题也日渐受到重视。技术革新…...
如何在 Mac 上重置网络设置
如何在 Mac 上重置网络设置 Mac 几乎在所有时间都非常可靠,但有时您在连接到互联网时可能会遇到困难或浏览速度缓慢。 互联网可能在您的其他设备上正常工作,这可能很烦人。 通常,问题的原因是什么并不明显,甚至根本不存在。 如果…...
BVH动画绑骨蒙皮并在Unity上展示
文章目录 Blender绑定骨骼Blender蒙皮Blender中导入bvh文件将FBX导入Unity Blender绑定骨骼 先左上角红框进入model模式,选中要绑定的模型,然后进入Edit模式把骨骼和关节对齐。 (选中骨骼,G移动,R旋转) 为…...
c# 缓存帮助类
public class CacheHelper { private static Dictionary<string, object> dic new Dictionary<string, object>(); // 定义一个静态变量来保存类的实例 private static CacheHelper session; // 定义一个标识确保线程同步 pr…...
红队渗透靶机:TIKI: 1
目录 信息收集 1、arp 2、nmap 3、nikto 4、whatweb 目录探测 1、dirsearch 2、gobuster WEB web信息收集 searchsploit cms信息收集 ssh登录 提权 信息收集 1、arp ┌──(root㉿ru)-[~/kali] └─# arp-scan -l Interface: eth0, type: EN10MB, MAC: 00:0c:2…...
【数据结构】二叉树的三种遍历(非递归讲解)
目录 1、前言 2、二叉树的非递归遍历 2.1、先序遍历 2.2、中序遍历 2.3、后序遍历 1、前言 学习二叉树的三种非递归遍历前,首先来了解一下递归序: 递归序就是按照先序遍历的顺序,遇到的所有结点按顺序排列,重复的结点也必须记…...
Spark Standalone 集群配置
前言 平时工作中主要用 YARN 模式,最近进行TPC测试用到了 Standalone 模式,便记录总结一下 Standalone 集群相关的配置。 集群管理类型 Spark 支持三种集群管理类型: Standalone - Spark附带的一个简单的集群管理器,可以轻松地设置集群。Apache Mesos - 一个通用的集群管…...
蓝桥杯Web应用开发-CSS3 新特性【练习二:获得焦点验证】
页面上有一个姓名输入框和一个密码输入框,当聚焦输入框时,输入框的背景颜色会发生改变, 新建一个 index3.html 文件,在其中写入以下内容。 <!DOCTYPE html> <html lang"en"><head><meta charset&…...
职业发展 - 一个专注于嵌入式物联网架构设计的攻城狮(转载)
1 关于我 很高兴大家都关注到我,从而看到这篇简要的介绍,下面有更多的关于我。 我是一个嵌入式架构师,早前从事过智能电网相关的电力设备开发,金融POS机开发,以及eSIM相关的软件开发,现在主要在做嵌入式I…...
阿里云ECS服务器Linux安装Mysql8
链接:https://pan.baidu.com/s/1s9j7OhiOMV9e9Qq9GDbysA 提取码:dd5a --来自百度网盘超级会员V5的分享 Mysql官网:MySQL 关于Mysql Yum Repository介绍可以看下 更加简单 关于X86和ARM 传到服务器 进入所在包 cd /usr/local/develop/mysql8 解压 …...
Redis中内存淘汰算法实现
Redis中内存淘汰算法实现 Redis的maxmemory支持的内存淘汰机制使得其成为一种有效的缓存方案,成为memcached的有效替代方案。 当内存达到maxmemory后,Redis会按照maxmemory-policy启动淘汰策略。 Redis 3.0中已有淘汰机制: noevictionall…...
人工智能(pytorch)搭建模型23-pytorch搭建生成对抗网络(GAN):手写数字生成的项目应用
大家好,我是微学AI,今天给大家介绍一下人工智能(pytorch)搭建模型23-pytorch搭建生成对抗网络(GAN):手写数字生成的项目应用。生成对抗网络(GAN)是一种强大的生成模型,在手写数字生成方面具有广泛的应用前景。通过生成…...
解决使用Springboot jpa update数据时报错Executing an update:delete query
解决org.springframework.dao.InvalidDataAccessApiUsageException: Executing an update/delete query; nested exception is javax.persistence.TransactionRequiredException: Executing an update/delete query 使用的Springboot jpa ,使用原生SQL方法实现数据更新时&…...
OpenCV-32 膨胀操作
膨胀是与腐蚀相反的操作,基本原理是只要保证卷积核的锚点是非0值,周边无论是0还是非0值,都变为0。 使用API---dilate(img, kernel, iterationms 1) 示例代码如下: import cv2 imp…...
7.0 Zookeeper 客户端基础命令使用
zookeeper 命令用于在 zookeeper 服务上执行操作。 首先执行命令,打开新的 session 会话,进入终端。 $ sh zkCli.sh 下面开始讲解基本常用命令使用,其中 acl 权限内容在后面章节详细阐述。 ls 命令 ls 命令用于查看某个路径下目录列表。…...
使用virtualenv管理python环境
Windows配置virtualenv 安装 pip install virtualenv virtualenvwrapper virtualenvwrapper-win设置WORK_HOME环境变量 在系统path变量中添加虚拟环境目录:键WORKON_HOMEC:dev\Envs 修改windows环境下mkvirtualenv.bat文件,配置虚拟环境根目录地址 配…...
Linux---线程
线程概念 在一个程序里的一个执行路线就叫做线程(thread)。更准确的定义是:线程是“一个进程内部的控制序列” 一切进程至少都有一个执行线程 线程在进程内部运行,本质是在进程地址空间内运行 在Linux系统中,在CPU眼中…...
解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...
[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...
华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...
全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...
JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...
站群服务器的应用场景都有哪些?
站群服务器主要是为了多个网站的托管和管理所设计的,可以通过集中管理和高效资源的分配,来支持多个独立的网站同时运行,让每一个网站都可以分配到独立的IP地址,避免出现IP关联的风险,用户还可以通过控制面板进行管理功…...
MySQL 部分重点知识篇
一、数据库对象 1. 主键 定义 :主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 :确保数据的完整性,便于数据的查询和管理。 示例 :在学生信息表中,学号可以作为主键ÿ…...
离线语音识别方案分析
随着人工智能技术的不断发展,语音识别技术也得到了广泛的应用,从智能家居到车载系统,语音识别正在改变我们与设备的交互方式。尤其是离线语音识别,由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力,广…...
前端开发者常用网站
Can I use网站:一个查询网页技术兼容性的网站 一个查询网页技术兼容性的网站Can I use:Can I use... Support tables for HTML5, CSS3, etc (查询浏览器对HTML5的支持情况) 权威网站:MDN JavaScript权威网站:JavaScript | MDN...
