list(二)和_stack_queue

news2024/11/26 23:40:28

在这里插入图片描述

嗨喽大家好,时隔许久阿鑫又给大家带来了新的博客,list的模拟实现(二)以及_stack_queue,下面让我们开始今天的学习吧!

list(二)和_stack_queue

1.list的构造函数

2.设计模式之适配器和迭代器

3.新容器deque

4.优先级队列

5.仿函数

1.list的构造函数

在这里插入图片描述

最好加上引用,如果不加引用,T为list时,将it解引用赋值给e时,list为自定义类型要耗费大量空间进行拷贝操作,所以在利用for语句时,我们最好加上引用

//list的默认构造,构造出一个头节点
void empty_init()
{
	//利用节点的默认构造,生成一个节点
	//定义该节点为头节点,节点对象拥有两个成员变量
	_head = new Node();
	_head->_next = _head;
	_head->_prev = _head;
}

list(initializer_list <T> il)
{
	//initializer_list常量数组中有两个指针,分别指向数组的开头和结尾
	empty_init();
	for (const auto& e : il)
	{
		push_back(e);
	}
}


list()
{
	//看一下交换的时候,是不是新创建的对象是调用默认构造进行初始化
	empty_init();
}

list(const list<T>& it)
{
	empty_init();
	for (const auto& e :it)
	{
		push_back(e);
	}
}

~list()
{
	clear();
	delete _head;
	_head = nullptr;
}

void clear()
{
	auto it = begin();
	while (it != end())
	{
		it = erase(it);
		
	}
}
//it1(it3)
list<T>& operator=(list<T> it)
{
	std::swap(_head, it._head);
	return *this;
}

2.设计模式之适配器和迭代器

using namespace std;
namespace ZJ
{
	template<class T, class Container = vector<T>>
	class Stack
	{
	public:

		void push(const T& x)
		{
			_con.push_back(x);
		}

		void pop()
		{//后进先出
			_con.pop_back();

		}

		const T& top()
		{
			return _con.back();
		}

		bool empty()
		{
			return _con.empty();
		}

		size_t size()
		{
			return _con.size();
		}





	private :
		Container _con;

	};

	void Test_stack1()
	{
		ZJ::Stack<int> st1;
		st1.push(1);
		st1.push(2);
		st1.push(3);
		st1.push(4);
		st1.push(5);
		int n = st1.size();
		for (int i = 0; i < n; i++)
		{
			cout << st1.top() << " ";
			st1.pop();
		}
		cout << endl;
	}





}

3.新容器deque

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

deque的每个对象有四个成员变量,每个迭代器中又有四个指针
cur指向当前数据,node(是一个二级指针)指向当前数据在中控数组中的位置,first和last分别指向buff数组中第一个和最后一个数据,而finish中的node指针指向最后一个buff的最后一个数据的下一个位置

在这里插入图片描述
在这里插入图片描述

4.优先级队列

底层是一个堆

在这里插入图片描述
在这里插入图片描述

void Test_priority_queue1()
{
	vector<int> v1 = { 1,2,3,8,9,7,5,6,4 };
	priority_queue<int> q1(v1.begin(), v1.end());
	//for (const auto& e : v1)
	//{
	//	q1.push(e);
	//
	//}

	while (!q1.empty())
	{
		cout << q1.top() << " ";
		q1.pop();
	}
	
}

堆逻辑上是一个二叉树,物理结构上是一个数组

在这里插入图片描述
在这里插入图片描述

没有引入仿函数时。

namespace ZJ
{
	template<class T, class Container = vector<T>>
	class priority_queue
	{
	public:

		template <class InputIterator>
		priority_queue(InputIterator first, InputIterator last)
		{
			while (first != last)
			{
				_con.push_back(*first);
				++first;
			}

			// 从最后一个非叶子节点开始向下建堆
			for (int i = (_con.size() - 1 - 1) / 2; i >= 0; i--)
			{
				adjust_down(i);
			}
		}

		void adjust_up(int child)
		{
			size_t parent = (child - 1) / 2;
			while (child > 0)
			{
				if (_con[parent] < _con[child])
				{
					swap(_con[parent], _con[child]);
					child = parent;
					parent = (child - 1) / 2;
				}
				else
				{
					break;
				}
			}
		}


		void push(const T& x)
		{
			_con.push_back(x);
			adjust_up(_con.size() - 1);
		}


		void adjust_down(int parent)
		{
			size_t child = parent * 2 + 1;
			while (child<_con.size())
			{
				if (child + 1 < _con.size() && _con[child] < _con[child + 1])
				{
					child = child + 1;
				}

				if (_con[child] > _con[parent])
				{
					swap(_con[parent], _con[child]);
					parent = child;
					child = parent * 2 + 1;
				}
				else
				{
					break;
				}
			}
		}

		void pop()
		{
			swap(_con[0], _con[_con.size() - 1]);
			_con.pop_back();

			adjust_down(0);
		}

		const T& top()
		{
			return _con[0];
		}

		size_t size()
		{
			return _con.size();
		}

		bool empty()
		{
			return _con.empty();
		}


	private:
		Container _con;

	};
}

5.1仿函数初识

>仿函数/函数对象,是一个重载了operator()的类。让类的对象可以像函数一样使用

class Func
{
public:

	void operator()(int a = 10)
	{
		while (a--)
		{
			cout << "Func调用" << endl;

		}
		
	}
};

有了仿函数之后的优先级队列

namespace ZJ
{

	template<class T>
	class myless
	{
	public:
		bool operator() (const T& x, const T& y)
		{
			return x < y;
		}

	};


	template<class T>
	class mygreater
	{
	public:
		bool operator() (const T& x, const T& y)
		{
			return x > y;
		}

	};



	template<class T, class Container = vector<T>,class compare = myless<T>>
	class priority_queue
	{
	public:

		template <class InputIterator>
		priority_queue(InputIterator first, InputIterator last)
		{
			while (first != last)
			{
				_con.push_back(*first);
				++first;
			}

			// 从最后一个非叶子节点开始向下建堆
			for (int i = (_con.size() - 1 - 1) / 2; i >= 0; i--)
			{
				adjust_down(i);
			}
		}

		void adjust_up(int child)
		{
			compare comfunc;
			size_t parent = (child - 1) / 2;
			while (child > 0)
			{
				if (comfunc(_con[parent],_con[child]))
				{
					swap(_con[parent], _con[child]);
					child = parent;
					parent = (child - 1) / 2;
				}
				else
				{
					break;
				}
			}
		}


		void push(const T& x)
		{
			_con.push_back(x);
			adjust_up(_con.size() - 1);
		}


		void adjust_down(int parent)
		{
			compare comfunc;
			size_t child = parent * 2 + 1;
			while (child<_con.size())
			{
				if (child + 1 < _con.size() && comfunc(_con[child] , _con[child + 1]))
				{
					child = child + 1;
				}

				if (comfunc(_con[parent],_con[child]))
				{
					swap(_con[parent], _con[child]);
					parent = child;
					child = parent * 2 + 1;
				}
				else
				{
					break;
				}
			}
		}

		void pop()
		{
			swap(_con[0], _con[_con.size() - 1]);
			_con.pop_back();

			adjust_down(0);
		}

		const T& top()
		{
			return _con[0];
		}

		size_t size()
		{
			return _con.size();
		}

		bool empty()
		{
			return _con.empty();
		}


	private:
		Container _con;

	};
}

给出的对创建存储自定义类型的vector和存储自定义类型指针的vector的解释

在这里插入图片描述

编译器通过类型信息来确保您不会将非 Date* 类型的指针错误地插入到 a 中。如果您尝试将一个不是 Date* 类型的指针插入到a 中,编译器会发出一个错误,告诉您类型不匹配。所以当我们创建存储Date*类型的vector时,不需要调用Date的构造函数,只有在创建Date对象的时候,我们才需要调用Date的构造函数。

并且上述程序我们需要注意:程序结束时,只有局部对象(如a数组本身和任何在栈上分配的局部变量)的生命周期会结束,但由new在堆上分配的对象不会自动被销毁。你需要手动管理这些对象的生命周期。

在这里插入图片描述
在这里插入图片描述

5.2仿函数用法之自定义类型比较大小

priority_queue() = default;//生成默认的构造函数
class Date
{
public:
	Date(int year = 1900, int month = 1, int day = 1)
		: _year(year)
		, _month(month)
		, _day(day)
	{}
	bool operator<(const Date& d)const
	{
		return (_year < d._year) ||
			(_year == d._year && _month < d._month) ||
			(_year == d._year && _month == d._month && _day < d._day);
	}
	bool operator>(const Date& d)const
	{
		return (_year > d._year) ||
			(_year == d._year && _month > d._month) ||
			(_year == d._year && _month == d._month && _day > d._day);
	}
	friend ostream& operator<<(ostream& _cout, const Date& d)
	{
		_cout << d._year << "-" << d._month << "-" << d._day;
		return _cout;
	}
private:
	int _year;
	int _month;
	int _day;
};
struct PDateLess
{
	bool operator() (Date* p1, Date* p2)
	{
		return *p1 < *p2;
	}
};
struct PDateMore
{
	//小堆
	bool operator() (Date* p1, Date* p2)
	{
		return *p1 > *p2;
	}
};
void TestPriorityQueue()
{
	// 大堆,需要用户在自定义类型中提供<的重载
	ZJ::priority_queue<Date*,vector<Date*>,PDateMore> q1;
	q1.push(new Date(2018, 10, 29));
	q1.push(new Date(2018, 10, 28));
	q1.push(new Date(2018, 10, 30));


	while(!q1.empty())
	{
		cout << *q1.top() << endl;
		q1.pop();
	}

	 如果要创建小堆,需要用户提供>的重载
	//priority_queue<Date, vector<Date>, greater<Date>> q2;
	//q2.push(Date(2018, 10, 29));
	//q2.push(Date(2018, 10, 28));
	//q2.push(Date(2018, 10, 30));
	//cout << q2.top() << endl;
}
int main()
{

	TestPriorityQueue();


	return 0;
}

好啦,今天的内容我们就学习到这里,如果大家觉得阿鑫写的不错的话,记得留下你的一键三连哦,期待我们的下一次相遇!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1796899.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HTML静态网页成品作业(HTML+CSS)—— 保护环境环保介绍网页(1个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有1个页面。 二、作品演示 三、代…

公检法部门保密网文件导出,这样做才是真正的安全又便捷

公检法是司法机关的核心组成&#xff0c;也是社会管理的重要组成&#xff0c;公检法部门的业务中涉及大量的居民数据、个人隐私、司法案件等信息&#xff0c;因此&#xff0c;数据的安全性至关重要。 根据我国法律要求&#xff0c;同时基于对数据的保护需要&#xff0c;我国的公…

Vue06-el与data的两种写法

一、el属性 用来指示vue编译器从什么地方开始解析 vue的语法&#xff0c;可以说是一个占位符。 1-1、写法一 1-2、写法二 当不使用el属性的时候&#xff1a; 两种写法都可以。 v.$mount(#root);写法的好处&#xff1a;比较灵活&#xff1a; 二、data的两种写法 2-1、对象式…

discuz点微同城源码34.7+全套插件+小程序前端

discuz点微同城源码34.7全套插件小程序前后端 模板挺好看的 带全套插件 自己耐心点配置一下插件 可以H5可以小程序

重磅就业报告前美股涨势消减,标普暂别纪录高位,英伟达盘中闪崩近6%,欧央行降息预期“退烧”,欧元跳涨

标普纳指创盘中历史新高后转跌&#xff0c;道指三连涨至近两周新高&#xff1b;芯片股指和台积电美股跌落纪录高位&#xff0c;英伟达三日收创历史新高后回落&#xff1b;游戏驿站盘中一度暴拉50%。中概股指回落&#xff0c;财报后蔚来收跌6.8%。欧央行会后&#xff0c;欧元盘中…

Dvws靶场

文章目录 一、XXE外部实体注入二、No-SQL注入三、Insecure Direct Object Reference四、Mass Assignment五、Information Disclosure六、Command Injection七、SQL注入 一、XXE外部实体注入 访问http://192.168.92.6/dvwsuserservice?wsdl&#xff0c;发现一个SOAP服务。在SO…

Golang | Leetcode Golang题解之第136题只出现一次的数字

题目&#xff1a; 题解&#xff1a; func singleNumber(nums []int) int {single : 0for _, num : range nums {single ^ num}return single }

【微信小程序】页面事件

下拉刷新 上拉触底 上拉触底距离指的是触发上拉触底事件时&#xff0c;滚动条距离页面底部的距离。 可以在全局或页面的json配置文件中&#xff0c;通过onReachBottomDistance属性来配置上拉触底的距离。 小程序默认的触底距离是50x,在实际开发中&#xff0c;可以根据自己的需…

三石峰汽车生产厂的设备振动检测项目案例

汽车生产厂的设备振动检测项目 ----天津三石峰科技&#xff08;http://www.sange-cbm.com&#xff09; 汽车产线有很多传动设备需要长期在线运行&#xff0c;会出现老化、疲劳、磨损等问题&#xff0c;为了避免意外停机造成损失&#xff0c;需要加装一些健康监测设备&#xf…

002.数据分析_Pandas初识

我 的 个 人 主 页&#xff1a;&#x1f449;&#x1f449; 失心疯的个人主页 &#x1f448;&#x1f448; 入 门 教 程 推 荐 &#xff1a;&#x1f449;&#x1f449; Python零基础入门教程合集 &#x1f448;&#x1f448; 虚 拟 环 境 搭 建 &#xff1a;&#x1f449;&…

基于pulseaudio实现一个边录边播的demo

文章目录 前言一、主要APIpa_simple_newpa_simple_readpa_simple_write 二、C代码实现三、注意事项1、必须装有 libpulsedev 包2、编译方式3、运行说明 前言 通过上一讲&#xff0c;我们实现了一个加载pulseaudio的module-loopback的功能来实现侦听&#xff0c;那么除了加载模…

软件杯 题目:基于深度学习卷积神经网络的花卉识别 - 深度学习 机器视觉

文章目录 0 前言1 项目背景2 花卉识别的基本原理3 算法实现3.1 预处理3.2 特征提取和选择3.3 分类器设计和决策3.4 卷积神经网络基本原理 4 算法实现4.1 花卉图像数据4.2 模块组成 5 项目执行结果6 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基…

【Python深度学习系列】网格搜索神经网络超参数:批量大小和迭代周期数(案例+源码)

这是我的第297篇原创文章。 一、引言 在深度学习中&#xff0c;超参数是指在训练模型时需要手动设置的参数&#xff0c;它们通常不能通过训练数据自动学习得到。超参数的选择对于模型的性能至关重要&#xff0c;因此在进行深度学习实验时&#xff0c;超参数调优通常是一个重要的…

C++初阶学习第十一弹——探索STL奥秘(六)——深度刨析list的用法和核心点

前言&#xff1a; 在前面&#xff0c;我们已经学习了STL中的string和vector&#xff0c;现在就来讲解STL中的最后一个部分——list的使用及其相关知识点&#xff0c;先说明一点&#xff0c;因为我们之前已经讲过了string和vector的接口函数等用法&#xff0c;list的这些用法与它…

【Python报错】已解决IndentationError: expected an indented block

解决Python报错&#xff1a;IndentationError: expected an indented block Python是一种非常注重可读性的编程语言&#xff0c;其中缩进是语法的一部分。如果你在使用Python时遇到了IndentationError: expected an indented block的错误&#xff0c;这意味着你的代码缩进不正确…

Bandizip 专业版正版激活码 - 超好用文件解压缩工具

要说新电脑必装的软件&#xff0c;一定少不了解压缩工具。面对各式各样的压缩包&#xff0c;总要有一个速度快、稳定安全、功能多、支持格式广的工具才行。 好多用户推荐&#xff0c;用过都说好的 Win 端解压缩工具&#xff1a;Bandizip 值得你一试&#xff01; 无论是解压速度…

Python必会的UnitTest单元测试框架详解单元测试框架

用Python搭建自动化测试框架&#xff0c;我们需要组织用例以及测试执行&#xff0c;这里博主推荐Python的标准库——UnitTest。 什么是UnitTest框架 UnitTest单元测试框架详解是xUnit系列框架中的一员&#xff0c;如果你了解xUnit的其他成员&#xff0c;那你用UnitTest单元测试…

【Python报错】已解决AttributeError: ‘function‘ object has no attribute ‘read‘

解决Python报错&#xff1a;AttributeError: ‘function’ object has no attribute ‘read’ 在使用Python进行文件操作时&#xff0c;我们经常使用open函数来打开文件&#xff0c;并使用read方法来读取文件内容。如果你遇到了AttributeError: function object has no attribu…

DL4YHF频率计折腾记

DL4YHF大佬原创的频率计https://www.qsl.net/dl4yhf/freq_counter/freq_counter.html有很多种魔改型号&#xff0c;各位大佬都开源了代码。 DL4YHF频率计电路十分简洁&#xff0c;本来想自己DIY一个&#xff0c;动手之前在淘宝一搜&#xff0c;果然没有让我失望&#xff0c;一…

Linux驱动应用编程(三)UART串口

本文目录 前述一、手册查看二、命令行调试串口1. 查看设备节点2. 使用stty命令设置串口3. 查看串口配置信息4. 调试串口 三、代码编写1. 常用API2. 例程线程优化 前述 在开始实验前&#xff0c;请一定要检查测试好所需硬件是否使用正常&#xff0c;不然调试过程中出现的问题&am…