典型数据结构的模板实现

news/2024/7/24 9:07:18 标签: 数据结构, c++, 算法

栈和数组

  • 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

可变数组

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;
        }
        // 判空函数,即判断栈顶指针是否为0
        bool 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;
        }

这样我们就成功的做出了一个模板类实现栈的部分功能了。


http://www.niftyadmin.cn/n/5364249.html

相关文章

ubuntu 安装 ffmpeg 6.0

# ubuntu 22 sudo add-apt-repository ppa:ubuntuhandbook1/ffmpeg6 sudo apt update sudo apt install ffmpeg ffmpeg --version# 删除源 sudo add-apt-repository --remove ppa:ubuntuhandbook1/ffmpeg6 参考&#xff1a; FFmpeg 6.0 Released! How to Install in Ubuntu 22…

新版MQL语言程序设计:代理模式的原理、应用及代码实现

文章目录 一、什么代理模式二、代理模式的实现原理三、代理模式应用场景四、代理模式的代码实现 一、什么代理模式 代理模式是一种结构型设计模式&#xff0c;它允许通过创建一个代理对象来控制对另一个对象的访问。代理对象充当了客户端和目标对象之间的中介&#xff0c;可以在…

【MySQL】学习并使用DQL实现排序查询和分页查询

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-SP91zTA41FlGU0Ce {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

docker入门问题二

一、什么是Dockerfile&#xff0c;它的作用是什么&#xff1f; Dockerfile是一个文本文件&#xff0c;其中包含了一组用于构建Docker镜像的指令和参数。这些指令应用于一个基础镜像&#xff0c;并通过层叠的修改步骤来创建新的镜像。Dockerfile提供了一种可重复且自动化的方式…

机器视觉系统设计:视觉系统中的成像基准

开发视觉系统的一个重要活动是验证其部署是否符合工程规范。一个成功的视觉应用程序的两个特点是它无需工程师干涉情况下正常工作了多长时间&#xff0c;以及它的维护和复制部署是多么简易。实现所有如上所述目标的一个关键步骤是确定视觉系统的基准。 在这里使用的上下文中&a…

ffmpeg的使用,安装,抽帧,加水印,截图,生成gif,格式转换,抓屏等

实际使用中总结的关于ffmpeg对视频的处理的记录文档 具体信息&#xff1a; http://ffmpeg.org/download.html 官网下载ffmpeg 关于ffmpeg的安装详细步骤和说明 装ffmpeg 方式,Linux和windows下的 http://bbs.csdn.net/topics/390519382 php 调用ffmpeg , http://bbs.csdn.net/t…

【npm】修改npm全局安装包的位置路径

问题 全局安装的默认安装路径为&#xff1a;C:\Users\admin\AppData\Roaming\npm&#xff0c;缓存路径为&#xff1a;C:\Users\admin\AppData\Roaming\npm_cache&#xff08;其中admin为自己的用户名&#xff09;。 由于默认的安装路径在C盘&#xff0c;太浪费C盘内存啦&#…

Flutter开发模仿百度云盘创建文件夹功能Draggable和DragTarget的混合使用

使用LongPressDraggable和DragTarget写了个类似于百度云盘管理文件和文件夹的功能&#xff08;为了避免和列表的滑动手势冲突&#xff0c;所以采用LongPressDraggable而不是Draggable&#xff09;&#xff1a; 1、拖拽文件到文件夹中 2、拖拽两个文件可以合并成一个新的文件夹…