C++ 模拟实现stack,queue/仿函数

 

目录

 1.stack

2.queue

3.优先级队列priority_queue

优先级队列额外的构造函数(通过区间构造)

​4.仿函数

仿函数与函数指针

显式地写greater和less


 1.stack

#pragma once
#include<vector>
#include<list>
#include<deque>

namespace bit//将实现的栈封装到bit中
{
	// 常规实现数据结构的思路
	//template<class T>
	//class stack
	//{
	//public:
	//	// ....
	//private:
	//	T* _a;
	//	size_t _size;
	//	size_t _capacity;
	//};

	// 容器适配器
	//template<class T, class Container = std::vector<T>>
	//template<class T, class Container = std::list<T>>
	template<class T, class Container = std::deque<T>>
	class stack
	{
	public:
		void push(const T& x)
		{
			_con.push_back(x);
		}

		void pop()
		{
			_con.pop_back();
		}

		/*T top()
		{
			return _con.back();
		}*/

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


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

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

	private:
		Container _con;
	};
}

stl源码中的实现

 测试:使用string类型数据时容易出现溢出或者截断,存入数据300测试

void test_stack()
	{
		//stack<int> s;
		stack<int, vector<int>> s;
		//stack<int, list<int>> s;
		//stack<int, string> s; // ????

		s.push(1);
		s.push(2);
		s.push(3);
		s.push(4);
		s.push(300);

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

300转换为44 ,故stack<int,string>s存在截断数据丢失的风险

2.queue

#pragma once

namespace bit
{
	// list
	template<class T, class Container = deque<T>>
	class queue
	{
	public:
		void push(const T& x)
		{
			_con.push_back(x);
		}

		void pop()
		{
			_con.pop_front();
		}

		/*T front()
		{
			return _con.front();
		}*/

        const T& front()
		{
			return _con.front();
		}

		/*T back()
		{
			return _con.back();
		}*/

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

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

		bool empty()
		{
			return _con.empty();
		}
	private:
		Container _con;
	};
}

注:队列不能使用vector适配,因为vector不支持pop_front()的接口

3.优先级队列priority_queue

#pragma once

namespace bit
{
	template<class T>
    
    //仿函数/函数对象  -- 对象可以像调用函数一样去使用
	struct less
	{
		bool operator()(const T& l, const T& r)//仿函数重载运算符
		{
			return l < r;
		}
	};


	template<class T>
	struct greater
	{
		bool operator()(const T& l, const T& r)
		{
			return l > r;
		}
	};

	template<class T, class Container = vector<T>, class Compare = std::less<T>>
	class priority_queue
	{
	public:
		//typedef typename Container::value_type VT;

		void AdjustUp(size_t child)
		{
			Compare com;//compare是一个仿函数

			size_t parent = (child - 1) / 2;
			while (child > 0)
			{
				//if (_con[parent] > _con[child])
				if (com(_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);

			AdjustUp(_con.size() - 1);
		}

		void AdjustDwon(size_t parent)
		{
			Compare com;
			size_t child = parent * 2 + 1;
			while (child < _con.size())
			{
				//if (child+1 < _con.size() && _con[child] > _con[child+1])
				if (child+1 < _con.size() && com(_con[child], _con[child+1]))//使用仿函数比较
				{
					++child;
				}

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

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

			AdjustDwon(0);
		}

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

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

		bool empty()
		{
			return _con.empty();
		}
	private:
		Container _con;
	};
}

对于插入函数接口,使用向上调整使之为堆

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

			AdjustUp(_con.size() - 1);
		}

 测试

void test_priority_queue()
	{
		/*less<int> LessCom;
		cout << LessCom(1, 2) << endl;

		greater<int> GreaterCom;
		cout << GreaterCom(1, 2) << endl;*/

		//priority_queue<int> pq;
		priority_queue<int, vector<int>, greater<int>> pq;

		pq.push(2);
		pq.push(5);
		pq.push(1);
		pq.push(6);
		pq.push(8);

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

优先级队列额外的构造函数(通过区间构造)

template <class InputIterator>
		priority_queue(InputIterator first, InputIterator last,
			const Compare& comFunc = Compare())
			: _comFunc(comFunc)
		{
			while (first != last)
			{
				_con.push_back(*first);
			}

			//建堆
			for (int i = (_con.size() - 1 - 1) / 2; i >= 0; --i)
			{
				AdjustDown(i);
			}
		}

解决TopK问题:建立大堆 

void test_priotity_queue2()
	{
		int a[] = { 1,4,2,7,8,9 };
		priority_queue<int>pq(a,a+6);
	}

4.仿函数

 

仿函数与函数指针

 

	template<class T>
	struct less
	{
		bool operator()(const T& x, const T& y) const
		{
			return x < y;
		}
	};

	template<class T>
	struct greater
	{
		bool operator()(const T& x, const T& y) const
		{
			return x > y;
		}
	};

	// 优先级队列 -- 大堆 <  小堆 >
	template<class T, class Container = vector<T>, class Compare = less<T>>
	class priority_queue
	{
	public:
		priority_queue(const Compare& comFunc = Compare())
			:_comFunc(comFunc)
		{}

		void AdjustUp(int child)
		{
			//Compare comFunc;
			int parent = (child - 1) / 2;
			while (child > 0)
			{
				//if (_con[parent] < _con[child])
				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);

			AdjustUp(_con.size() - 1);
		}

		void AdjustDown(int parent)
		{
			//Compare comFunc;
			size_t child = parent * 2 + 1;
			while (child < _con.size())
			{
				//if (child+1 < _con.size() && _con[child] < _con[child+1])
				if (child + 1 < _con.size() && _comFunc(_con[child], _con[child + 1]))
				{
					++child;
				}

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

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

			AdjustDown(0);
		}

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

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

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

	private:
		Compare _comFunc;
		Container _con;
	};

	void test_priority_queue()
	{
		/*less<int> LessCom;
		cout << LessCom(1, 2) << endl;

		greater<int> GreaterCom;
		cout << GreaterCom(1, 2) << endl;*/

		//priority_queue<int> pq; //使用缺省的 大堆 
		//priority_queue<int, vector<int>, greater<int>> pq; //传仿函数 小堆
		priority_queue<int, vector<int>, bool(*)(int, int)>pq; //传函数指针

		pq.push(2);
		pq.push(5);
		pq.push(1);
		pq.push(6);
		pq.push(8);

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

}

调用默认构造函数初始化后,测试样例中传函数指针出现崩溃。传入函数指针时,compare就为函数指针,用函数指针定义了一个缺省的对象

 此处显式地传了一个参数,其类型就没有用less,用的函数指针(内置类型)。用函数指针定义一个缺省的对象就是空指针,空指针此处调用不了东西

 程序运行的思路

 不用默认构造函数初始化,函数指针作为内置类型的成员,我们不初始化时为随机值

使传入函数指针后可成功运行的调整:在构造函数时把函数指针传递过去(函数名即为函数指针)

 

显式地写greater和less

默认情况下使用库里面的greater和less即可,某些情况下需要显式实现greater和less

void test_Functional()
	{
		vector<int>v;
		v.push_back(2);
		v.push_back(1);
		v.push_back(4);
		v.push_back(5);
		v.push_back(3);

		for (auto e : v)
		{
			cout << e << " ";
		}
		cout << endl;

        //less
		sort(v.begin(),v.end());//传迭代器区间,默认按升序排序

		for (auto e : v)
		{
			cout << e << " ";
		}
		cout << endl;
	}

若想实现降序。此处传的是greater的对象

//greater
		sort(v.begin(), v.end(), greater<int>());
		for (auto e : v)
		{
			cout << e << " ";
		}
		cout << endl;

对数组进行排序

//指向数组的原生指针本省就是天然的迭代器
		int  a[6] = { 1,2,5,2,5,7 };
		sort(a, a + 6);
		sort(a, a + 6, greater<int>());

若存在自定义类型的数组或者vector里面存储的是自定义类型,则需要写仿函数

    struct Goods
	{
		string _name;
		double _price;
		size_t _saleNum;
		//...

		bool operator<(const Goods& g1, const Goods& g2)const
		{
			return _price < g.price;
		}
	};

		Goods gds[4] = { { "苹果", 2.1, 1000}, { "香蕉", 3.0, 200}, { "橙子", 2.2,300}, { "菠萝", 1.5,50} };
		sort(gds, gds + 4);

若想按价格,可写一个仿函数按价格排序

struct LessPrice
	{
		bool operator<(const Goods& g1, const Goods& g2)const
		{
			return g1._price < g2._price;
		}
	};
	struct GreaterPrice
	{
		bool operator<(const Goods& g1, const Goods& g2)const
		{
			return g1._price > g2._price;
		}
	};

按销量来比较

    struct LessSaleNum
	{
		bool operator<(const Goods& g1, const Goods& g2)const
		{
			return g1._saleNum < g2._saleNum;
		}
	};
	struct GreaterSaleNum
	{
		bool operator<(const Goods& g1, const Goods& g2)const
		{
			return g1._salNum > g2._salNum;
		}
	};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值