【C++】stack、queue模拟实现+仿函数

这篇具有很好参考价值的文章主要介绍了【C++】stack、queue模拟实现+仿函数。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


铁汁们,今天给大家分享一篇stack、queue模拟实现+仿函数,来吧,开造⛳️

stack

定义

【C++】stack、queue模拟实现+仿函数,c++,开发语言,数据结构,算法

  • stack是容器适配器,专门用于进行”先进后出”操作的环境中,只能在容器的一端进行数据的插入和删除操作,元素在特定容器的尾部(即栈顶)被压入和弹出。
  • 容器适配器是将特定的类进行封装,将其作为该容器的底层容器,通过调用底层容器提供的一系列成员函数来实现该容器。
  • stack的底层容器既可以是任何标准容器类模板(list、vector、deque),也可以是其他特定的容器类,它必须支持以下操作:push_back()->入栈、pop_back()->出栈、back()->获取栈顶元素、empty()->判断栈是否为空、size()->获取栈中元素总个数。
  • stack底层容器可以是list、vector、deque,若未实例化指定特定的底层容器,则默认为deque。
  • 栈空间从高地址往低地址方向增长,堆从低地址往高地址方向增长。
template<class T, class Container = deque<T>> 
class stack {

private:
	Container _con;
};

stack模拟实现

【C++】stack、queue模拟实现+仿函数,c++,开发语言,数据结构,算法【C++】stack、queue模拟实现+仿函数,c++,开发语言,数据结构,算法

template<class T, class Container = deque<T>> 
class stack {
public:
    stack()  //构造空栈
	{  }

	void push(const T& val)  //入栈
	{
		_con.push_back(val);
	}
		 
	void pop()  //出栈
	{
		_con.pop_back();
	}
		 
	T& top() //获取栈顶元素 可读可修改
	{
		return _con.back();
	}

	const T& top()const  //获取栈顶元素 只可读不可修改
	{
		return _con.back();
	}

	bool empty()const  //判断栈是否为空
	{
		return _con.empty();
	}
		 
	size_t size()const //获取栈中元素的总个数
	{
		return _con.size();
	}

private:
	Container _con;  //底层容器创建的对象
};

queue

定义

  • queue是容器适配器,专门用于进行”先进先出”操作的环境中,从容器的一端插入数据并从容器的另一端取出数据。
  • 容器适配器是将特定的类进行封装,将其作为该容器的底层容器,通过调用底层容器提供的一系列成员函数来实现该容器。
  • queue的底层容器既可以是某些标准容器类模板(list、deque),也可以是其他特定的容器类,它必须支持以下操作:push_back()->入队、pop_front()->出队、back()->获取队尾元素、front()->获取队头元素、empty()->判断队列是否为空、size()->获取队列中元素总个数。
  • queue底层容器可以是list、deque,但不可以是vector(没有支持pop_front()),若未实例化指定特定的底层容器,则默认为deque。
  • 队列从队尾入队列,从队头从队列。
template<class T, class Container = deque<T>>
class queue {

private:
	Container _con; //底层容器创建的对象
};

queue模拟实现

【C++】stack、queue模拟实现+仿函数,c++,开发语言,数据结构,算法【C++】stack、queue模拟实现+仿函数,c++,开发语言,数据结构,算法

template<class T, class Container = deque<T>>
class queue {
public:
    queue() //构造空队列
	{ }

	void push(const T& val)  //入队
	{
		_con.push_back(val);
	}

	void pop() //出队
	{
		_con.pop_front();
	}

	T& front() //获取队头元素 可读可修改
	{
		return _con.front();
	}

	const T& front()const  //获取队头元素 只可读不可修改
	{
		return _con.front();
	}

	T& back()  //获取队尾元素
	{
		return _con.back();
	}

	const T& back()const //获取队尾元素 只可读不可修改
	{
		return _con.back();
	}

	bool empty()const  //判断队列是否为空
	{
		return _con.empty();
	}

	size_t size()const  //获取队列中元素的总个数
	{
    	return _con.size();
	}

private:
	Container _con; //底层容器创建的对象
};

priority_queue

定义

【C++】stack、queue模拟实现+仿函数,c++,开发语言,数据结构,算法

  • priority_queue为优先队列,是容器适配器,默认情况下元素呈降序排列,且它的第一个元素总是它所有元素中最大的。
  • 容器适配器是将特定的类进行封装,将其作为该容器的底层容器,通过调用底层容器提供的一系列成员函数来实现该容器。元素从优先队列的顶部弹出。
  • priority_queue的底层容器既可以是某些标准容器类模板(vector、deque),也可以是其他特定的容器类,它必须支持以下操作:push_back()->插入元素、pop_back()->删除元素、front()->获取优先队列顶部的元素、empty()->判断优先队列是否为空、size()->获取优先队列中元素总个数。
  • priority_queue底层容器可以是vector、deque,但不可以是list(不支持随机访问[]),若未实例化指定特定的底层容器,则默认为vector。
  • priority_queue底层结构为堆,所有需要用到堆的地方,都可以考虑使用priority_queue。默认情况下为大堆,即小于less-》降序(大堆),greater-》升序(小堆)。
  • priority_queue底层容器要支持随机访问,以保持堆的结构。在堆中可以随时插入数据,且只检索到最大元素(大堆)或者最小元素(小堆)。
template<class T, class Container = vector<T>, class Compare = less<T>>
class priority_queue {

private:
	Container _con;
	Compare _com;
};

priority_queue模拟实现

【C++】stack、queue模拟实现+仿函数,c++,开发语言,数据结构,算法

💡void push(const T& val) ;

  • 方法: 在堆的底部插入元素,在采用向上调整法

【C++】stack、queue模拟实现+仿函数,c++,开发语言,数据结构,算法

💡void pop( )

  • 方法: 堆顶元素和堆中最后一个元素交换,在删除最后一个元素,在采用向下调整法

【C++】stack、queue模拟实现+仿函数,c++,开发语言,数据结构,算法

//仿函数:功能像函数,但它就是个类模板,重载了operator(),通过将其设置为类模板参数,在其他类中通过该参数创造出对象,直接()调用
template<class T> //设计为类模板,泛型编程,是为了支持所有数据类型的比较
class less {  //小于
public:
	bool operator()(int x, int y)
	{
		return x < y;
	}
};

template<class T>
class greater { //大于
public:
	bool operator()(int x, int y)
	{
		return x > y;
	}
};

template<class T, class Container = vector<T>, class Compare = less<T>>
class priority_queue {//默认为大堆,且底层容器为vector
public:
	priority_queue()  //构造空优先队列
	{ }

	void Adjust_up(int child)  //向上调整法
	{
		int parent = (child - 1) / 2;
		while (child > 0)
		{
			if (_com(_con[parent], _con[child])) 
			{
				std::swap(_con[child], _con[parent]);
				child = parent;
				parent = (child - 1) / 2;
			}
			else
				break;
		}
	}

	void Adjust_down(int parent) //向下调整法
	{ //找到左、右孩纸中最大一个 -》假设法,假设左孩纸大,在与右孩纸进行比较
		int child = parent * 2 + 1;  
		if (child + 1 < _con.size() && _com(_con[child], _con[child + 1]))
			++child;

		while (child < _con.size()) 
		{
			if (_com(_con[parent] ,_con[child])) // 默认情况下为大堆,大的优先级高
			{
				std::swap(_con[child], _con[parent]);
				parent = child;
    			child = parent + 1;
			}
			else
				break;  //前提:该堆已经是个大堆(小堆)了
		}
	}

	void pop() //堆顶元素和堆中最后一个元素交换,在删除最后一个元素,在采用向下调整法
	{
		std::swap(_con[0], _con[size() - 1]);
		_con.pop_back();

		Adjust_down(0);
	}

	void push(const T& val) //在堆的底部插入元素,在采用向上调整法
	{
		_con.push_back(val); 

		Adjust_up(size() - 1);
	}

	const T& top()const //获取优先队列中顶部元素,即:堆顶元素
	{
		return _con.front();
	}

	bool empty()const  //判断优先队列是否为空
	{
		return _con.empty();
	}

	int size()const  //获取优先队列中总元素个数
	{
		return _con.size();
	}

private:
	Container _con;  //底层容器创建的对象
	Compare _com;  //仿函数类创建的对象
};

deque

定义

  • deque是双端队列,是一种双开口的“连续”空间的数据结构,可以在头尾进行插入和删除操作,时间复杂度为O(1),与vector相比,头插效率高,不需要挪动数据,与list相比,空间利用率高,缓存命中率高。
  • deque实际上并不是连续的空间,而是由一段段连续的小空间拼接而成,为了维护其"整体的连续"以及随机访问。deque底层类似于动态二维数组。
    【C++】stack、queue模拟实现+仿函数,c++,开发语言,数据结构,算法

底层分析

【C++】stack、queue模拟实现+仿函数,c++,开发语言,数据结构,算法【C++】stack、queue模拟实现+仿函数,c++,开发语言,数据结构,算法

  • 与list相比 ,缓存命中率高,空间利用率高,因为deque底层空间连续。deque支持随机访问。
  • 与vector相比 ,对于在头、尾部插入和删除上,效率高于vector,因为不需要挪动数据。对于在扩容消耗上,效率高于vector,因为不需要频繁挪动数据,只要"中控"满了扩容就可以了,且只需要拷贝指针(4个字节)。
  • stack和deque为容器适配器,不需要遍历数据,所以它们没有迭代器,只需要在固定一端或者两端进行插入和删除数据。在插入元素时,deque效率高于vector(扩容消耗小),相比于list,deque不仅头、尾插效率高,且内存利用率高。综上所述,选择deque作为stack和deque默认的底层容器更有优势。

容器适配器

定义

  • 适配器是一种设计模式,该模式是将一种接口转换成另一种接口。
  • 容器适配器是一个对特定的类进行封装的类模板,它在底层容器的基础上提供了一些其他的功能。它是适配其他容器来提供不同的功能,通过调用底层容器提供的一系列成员函数来实现我们需要的功能。
  • stack和queue都可以存储元素,但未将他们划分到容器序列,而是将他们称为容器适配器,是因为stack和queue是对其他容器进行了封装,默认情况下,stack和queue的底层容器为deque。
    【C++】stack、queue模拟实现+仿函数,c++,开发语言,数据结构,算法
  • 💡Tips : 容器适配器中不存在迭代器。

种类

三种容器适配器:stack、queue、priority_queue。

【C++】stack、queue模拟实现+仿函数,c++,开发语言,数据结构,算法

仿函数

  • 💡仿函数:又称为函数对象,是一个重载了operator()运算符的类。
  • 仿函数,不是函数,在语法上与普通函数调用的语法调用一样,在功能上仿函数通过创建的对象去调用operator()运算符,从而达到函数一样的功能。
//仿函数
template<class T>
class less { //小于
public:
    bool operator()(int x, int y)
    {
    	return x < y;
    }
};

 template<class T>
class greater {  //大于
public:
    bool operator()(int x, int y)
    {
    	return x > y;
    }
};
void test()
{
	less<int> LessFu;
	cout << LessFu(3, 4) << endl;

	greater<int> GreaterFu;
	cout << GreaterFu(3, 4) << endl;
}

int main()
{
    test();

	return 0;
}

【C++】stack、queue模拟实现+仿函数,c++,开发语言,数据结构,算法

控制类里面数据的比较逻辑

回调函数

  • 回调函数就是一个通过函数指针调用的函数。如果你把函数的地址作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说被调用的函数称为回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。
namespace yun {
	bool Less(int x, int y)
	{
		return x < y;
}

	bool Greater(int x, int y)
	{
		return x > y;
	}

	//在A这个类中调用
	class A1 {
	public:
		A1(bool(*pf)(int, int))
			:_pf(pf)
		{ }

		void fun(int x, int y)
		{
			cout << _pf(x, y) << endl;  //回调函数
		}

		bool(*_pf)(int, int);
	};

	//通过回调函数去调用:缺点-》函数指针类型抒写太复杂、需要通构构造函数参数传递(成员变量_pf为虚拟指针,无值)
	void test1()
	{
		A1 aa1(Less); 
		aa1.fun(3, 4);
		A1 aa2(Greater);
		aa2.fun(3, 4);
	}
}

int main()
{
	yun::test1();  //回调函数
    
	return 0;
}

【C++】stack、queue模拟实现+仿函数,c++,开发语言,数据结构,算法

仿函数

namespace yun {
    //仿函数
	template<class T>
	class less { //小于
	public:
		bool operator()(int x, int y)
		{
			return x < y;
		}
	};

	template<class T>
	class greater {  //大于
	public:
		bool operator()(int x, int y)
		{
			return x > y;
		}
	};

	template<class T, class Compare = less<T>> 
	class A2{  
	public:
		void fun(int x, int y)
		{
			cout << _com(x, y) << endl;  //调用仿函数,实际上就是通过类对象去调用operator()运算符
		}

	private:
		Compare _com; //创建仿函数对象
	};


	void test2() 
	{
		A2<int, less<int>> aa2;
		aa2.fun(5, 6);
		A2<int, greater<int>> aa3;
		aa3.fun(5, 6);
	}
}

int main()
{
	yun::test2();  //仿函数
    
	return 0;
}

【C++】stack、queue模拟实现+仿函数,c++,开发语言,数据结构,算法

两者区别

  • 回调函数缺点:函数指针类型相对比较复杂、只能通过函数参数传递(在类中,通过构造函数参数传递,且需要定义函数指针类型的成员变量,进行值的接收,从而实现回调。在普通函数中,通过函数参数直接传递)。
  • 仿函数优点:类型相对比较简单、只需要在类中创建对象,通过该对象去调用operator()运算符,就可以实现回调。

铁铁们,就到此结束啦,若博主有不好的地方,请指正,欢迎铁铁们留言,请动动你们的手给作者点个👍鼓励吧,你们的鼓励就是我的动力✨文章来源地址https://www.toymoban.com/news/detail-841450.html

到了这里,关于【C++】stack、queue模拟实现+仿函数的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • [C++] STL_stack && queue接口的模拟实现

    stack的文档介绍 1. stack是一种容器适配器,专门用在具有 后进先出 操作的上下文环境中,其删除只能从容器的一端进行元素的插入与提取操作。 2. stack是作为容器适配器被实现的,容器适配器即是对特定类封装作为其底层的容器,并提供一组特定的成员函数来访问其元素,将

    2024年02月05日
    浏览(32)
  • C++:stack、queue、priority_queue增删查改模拟实现、deque底层原理

    我们先来看看 stack的相关接口有哪些: 从栈的接口,我们可以知道栈的接口是一种特殊的vector,所以我们完全可以使用vector来模拟实现stack。 因此我们可以将底层容器定义成模板,然后将容器类变量作为成员变量进行封装。在实现satck的各种接口时,通过成员变量来调用底层

    2024年02月03日
    浏览(34)
  • 【C++】——栈和队列(stack、queue)及优先队列(priority_queue)的介绍和模拟实现

    今天我们来学习C++stl六大组件的其中一种,容器适配器,stack、queue及priority_queue都是容器适配器。我们循序渐进,接下来让我们先认识一下什么是容器适配器。 适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结),该

    2024年02月08日
    浏览(34)
  • 【C++】STL中的容器适配器 stack queue 和 priority_queue 的模拟实现

    适配器是一种设计模式 (设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结),该种模式是将一个类的接口转换成客户希望的另外一个接口。 例如我们常见的充电器就是一种适配器,它将我们常用的220V交流电压转化为4,5V (或者其他更高的电

    2023年04月26日
    浏览(48)
  • 容器适配器---deque和STL ---stack queue priority_queue的模拟实现 C++

    目录 一、容器适配器 deque原理 deque的缺陷 deque的优势 二、stack的模拟实现  三、queue的模拟实现 四、优先级队列的模拟实现 适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结),该种模式是将一个类的接口转换成客户

    2024年02月02日
    浏览(43)
  • C++入门之stl六大组件--stack和queue源码深度剖析及模拟实现

    目录 前言 一、stack的介绍和使用 1.stack的介绍 2.stack的使用 3.stack的模拟实现 二、queue的介绍和使用 1.queue的介绍 2.queue的使用 3.queue的模拟实现 三、priority_queue的介绍和使用 1.priority_queue的介绍 2.priority_queue的使用 3.priority_queue的模拟实现 3.1解决一个topK问题 四、容器适配器 1

    2024年02月14日
    浏览(38)
  • C++初阶:容器适配器介绍、stack和queue常用接口详解及模拟实现

    介绍完了list类的相关内容后:C++初阶:适合新手的手撕list(模拟实现list) 接下来进入新的篇章,stack和queue的介绍以及模拟: stack是一种容器适配器,专门用在具有后进先出操作的上下文环境中,其删除只能从容器的一端进行元素的插入与提取操作。 stack是作为容器适配器

    2024年02月19日
    浏览(30)
  • 【C++】STL中stack,queue容器适配器的模拟实现(使用deque容器)

    🌏博客主页: 主页 🔖系列专栏: C++ ❤️感谢大家点赞👍收藏⭐评论✍️ 😍期待与大家一起进步! 虽然stack和queue中也可以存放元素,但在STL中并没有将其划分在容器的行列,而是将其称为容器适配器,这是因为stack和队列只是对其他容器的接口进行了包装,STL中stack和

    2024年02月15日
    浏览(35)
  • stack&queue的模拟实现

    stack模拟: stack的源代码: stack的全部源代码就这些。 stack的代码少,原因在于采用了适配器模式,所谓适配器,以电器为例,每个电器都有电源适配器,中国的家用电源为220V的交流电,但是几乎没有电器需要220V的交流电,所以每个电器都有一个电源适配器,将家庭电压转换

    2024年02月06日
    浏览(31)
  • 模拟实现stack类与queue类

    前言: 本章我们将学习 stack 与 queue 的基本使用以及模拟实现。与前面已经学过的容器不同, stack 与 queue 属于 STL 六大组件之一的容器适配器范畴。 在 STL 中, stack 是一个模板类,用于实现栈数据结构。栈是一种后进先出(LIFO)的数据结构,可以在栈顶进行插入和删除操作

    2024年02月16日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包