从好奇到麻木:c++中的priority_queue类及反向迭代器的模拟实现

1.仿函数

        1.仿函数的作用

1.仿函数是一种重载了函数调用运算符的类对象,他的使用方法看起来与函数极其相似,却又有不同,因此成为仿函数

        2.仿函数的定义与使用

我们现在写一个比较两个变量大小的仿函数以及函数

template<class T>
class Less
{
	bool operator()(const T&a,const T&b )
	{
		return a < b;
	}
};
template<class T>
	bool  Less(const T& a, const T& b )
	{
		return a < b;
	}

仿函数的优势:复杂的函数指针很难看懂,而仿函数可以不用函数指针,直接传类,会简化操作

2.priority_queue

        1.priority_queue的介绍

1.优先队列是一种容器适配器,STL中默认使用的容器是vector(deque也可以)

2.它存储数据的结构是堆默认是大堆

3.底层容器可以是任何标准容器类模板,也可以是其他特定设计的容器类,容器应该可以通过随机访问迭代器访问,并支持以下操作:empty(判空操作),back(获取尾部元素操作),push_back(尾插操作),pop_back(尾删操作)

4.  需要支持随机访问迭代器,以便始终在内部保持堆结构。容器适配器通过在需要时自动调用算法函数make_heap、 push_heap 和 pop_heap 来自动完成此操作。

        2.成员变量
	template<class T, class Container = vector<T>, class Compare = Less<T>>
	class priority_queue
	{
	public:
		//函数
	private:
		Container _con;
	};

此处为直接模拟STL的格式,但事实上,在模板参数那里,应该把Container放到最后才合适,因为我们一般不会修改使用的容器,但会选择建一个大堆或小堆,STL的格式导致我们在调整为小堆时,必须也写容器才行

        3.empty
	bool empty()
	{
		reutrn _con.empty();
	}
        4.size(返回容器适配器的元素个数)
	size_t size()
	{
		return _con.size();
	}
        5.top(返回堆顶元素)
	constT& top()const
	{
		_con.front();
	}

必须返回const因为如果一旦使数据改变则堆将不是大堆或小堆

        6.入堆(尾插和向上调整)
		void push(T& val)
		{
			_con.push_back(val);
			UpAdjust();
		}
		void UpAdjust(size_t number)//大堆
		{
			int child = number - 1;
			int parent = child = (child-1) / 2;
			while (child)
			{
				if (_con[child] > _con[parent])
				{
					swap(_con[child], _con[parent]);
					child = parent;
					parent = (child-1) / 2;
				}
				else
					break;
 
			}
		}

此处可以使用模板,因为大堆和小堆只有大于号和小于号的区别

template<class T>
class Less
{
	bool operator()(const T&a,const T&b )
	{
		return a < b;
	}
};
template<class T>
class Greater
{
	bool operator()(const T& a, const T& b)
	{
		return a > b;
	}
};	
 
void push(T& val)
	{
		_con.push_back(val);
		UpAdjust();
	}
	Compare com;
	void UpAdjust(size_t number)//大堆
	{
		int child = number - 1;
		int parent = child = (child-1) / 2;
		while (child)
		{
			if (com(_con[parent] , _con[child]))
			{
				swap(_con[child], _con[parent]);
				child = parent;
				parent = (child-1) / 2;
			}
			else
				break;
 
		}
	}
        7.出堆(堆操作老套路,交换删除,堆顶向下调整,模板)
template<class T>
class Less
{
	bool operator()(const T&a,const T&b )
	{
		return a < b;
	}
};
template<class T>
class Greater
{
	bool operator()(const T& a, const T& b)
	{
		return a > b;
	}
};	
		Compare com;
		void DownAdjust(size_t size)
		{
			int parent = 0;
			int child = parent * 2+1;
			while (child<size)
			{
				if (child<size&&com(_con[child], _con[child + 1]))
					child++;
				if (com(_con[parent], _con[child]))
				{
					swap(_con[child], _con[parent]);
					parent = child;
					child = parent * 2 + 1;
				}
				else
					break;
			}
		}
 
	void pop()
	{
		swap(_con[0], _con[size() - 1]);
_con.pop_back();
		DownAdjust(size());
	}

3.反向迭代器

1.反向迭代器是一种适配器,它是根据不同容器的正向迭代器,来生成对应的反向迭代器

2.反向迭代器的rbegin对应迭代器的end位置,rend对应begin位置。

        1.成员变量
template <class Iterator,class Ref,class Ptr>
struct ReverseItreator
{
	typedef ReverseIterator<Iterator, Ref, Ptr> self;
	Iterator it;
};

使用struct标明公有属性的同时,将一个正向迭代器作为成员变量

        2.默认成员函数(只写缺省构造,其余编译器自动生成)
	ReverseItreator(Iterator val=Iterator())
		:it(val)
	{}
        3.operator*
	Ref operator*()
	{
		Iterator its = it;
		its--;
		return *its;
	}
        4.operator--(提醒一下这是反向迭代器哦)
self operator--()
{
	return ++it;
}
self operator--()const
{
	Iterator its = it;
	++it;
	return its;
}
        5.operator++
	self operator++()
	{
		return --it;
	}
	self operator++()const
	{
		Iterator its = it;
		--it;
		return its;
	}
        6.operator->
	Ptr operator->()
	{
		return  & (*it);
	}
        7.operator!=,==
	bool operator==(const self&s)
	{
		return it = s.it;
	}
	bool operator !=(const self& s)
	{
		return it = s.it;
	}

4.反向迭代器应用(vector为例)

template<class T>
class vector
{
public:
	typedef T* Iterator;
	typedef const T* Const_Iterator;
 
	typedef ReverseIterator<Iteartor, T&, T*> Reverse_Iterator;
	typedef ReverseIterator<Iteartor, constT&,cosnt T*> Const_Reverse_Iterator;
	Iterator end()
	{
		return _finish;
	}
	Const_Iterator end()const
	{
		return _finish;
	}
	Iterator begin()
	{
		return _start;
	}
	Const_Iterator begin()const
	{
		return _start;
	}
 
private:
	T* _start;
	T* _finish;
};

5.反向迭代器函数(使用时调用正向迭代器的函数,因为不同容器的函数各不相同)

	Reverse_Iterator rbegin()
	{
		return (Reverse_Iterator)end();
	}
	Const_Reverse_Iterator rbegin()const
	{
		return (Const_Reverse_Iterator)end();
	}
	Reverse_Iterator rend()
	{
		return (Reverse_Iterator)begin();
	}
	Const_Reverse_Iterator rend()const
	{
		return (Const_Reverse_Iterator)begin();
	}

  • 23
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值