(入门自用)C++--优先级队列--仿函数--0924

 优先级队列的模拟实现

#include<vector>
namespace chy
{
	template <class T,class Container = std::vector<T>,class Compare=std::less<T>>
	class priority_queue
	{
	public:
		//构造
		//建 大堆

		//直接使用内置类型的默认构造
		priority_queue()
		{}
		bool empty() const
		{
			return _con.empty();
		}
		const T& top()
		{
			return _con[0];
		}
		size_t size() const
		{
			return _con.size();
		}



		//构造
		template <class InputIterator>
		priority_queue(InputIterator first, InputIterator last)
		{
			while (first != last)
			{
				_con.push_back(*first);
				first++;
			}
			//建堆 向下调整
			for (int i = (_con.size() - 2) / 2; i >= 0; i--)
			{
				adjust_down(i);
			}

		}
		//删除  交换 -- 向下调整
		void pop()
		{
			std::swap(_con[0], _con[_con.size() - 1]);//交换首尾
			_con.pop_back();
			adjust_down(0);
		}

		//向下调整
		void adjust_down(int parent)
		{
			int child = parent * 2 + 1;
			while (child<_con.size())
			{
				if (child + 1 < _con.size() && _con[child] < _con[child + 1])
				{
					child++;
				}
				if (_con[parent] < _con[child])
				{
					std::swap(_con[parent], _con[child]);
					parent = child;
					child = parent * 2 + 1;
				}
				else
				{
					break;
				}
			}

		}
		void push(const T& x)
		{
			_con.push_back(x);//尾插
			adjust_up(_con.size()-1);//从当前位置进行调整
		}
		void adjust_up(int child)
		{
			int parent = (child - 1) / 2;
			while (child>0)
			{
				if (_con[parent] < _con[child])
				{
					std::swap(_con[parent], _con[child]);
					child = parent;
					parent = (child - 1) / 2;
				}
				else
				{
					break;
				}
			}
		}

	private:
		Container _con;
	};
}

问题:上述模拟实现的priority_queue是默认生成大堆,大堆与小堆的区别仅是比较时的符号不同。为了方便解决这一问题,模板中的第三个参数就有了作用

仿函数

仿函数本质是就是重载()运算符,相当于在一个类里面把括号重载,每次从该类中定义一个对象,在对象中使用()操作符。

namespace chy
{
    template<class T>
    class less
    {
    public:
        bool operator()(const T& a,const T& b)
        {
            return a<b;
        }
    }
    template<class T>
    class greater
    {
    public:
        bool operator()(const T& a,const T& b)
        {
            return a>b;
        }
    }
}
int main()
{
    chy::less<int> No_fun(1,2);
    //这里本质上从 less类中定义了一个No_fun对象 该对象使用操作符重载以比较大小
    cout<<No_fun(1,2)<<endl;//这里使用的less对象 即只能按照小于比较 
    chy::greater<int> No_func2(1,2);
    //这里本质上从 greater类中定义一个No_fun2对象
    cout<<No_fun2(1,2)<<endl;//这里使用的greater对象 即只能按照大于比较
    return 0;  
}

在priority_queue中以less为默认,用来实现大堆。

仿函数的优缺点

仿函数是模板函数,可以根据不同的类型代表不同的状态。仿函数是模板函数,可以有不同类型,更通用,本质上简化了代码。仿函数是模板函数,其速度比一般函数要慢

仿函数对于优先级队列的优化

std库里面有less和greater的实现

在每次需要比大小的时候都需要创建一个对象。以adjust_up为例。

	void adjust_up(size_t child)
	{
        //创建一个对象 没传的话就是默认less<T>
		Compare com;
		size_t parent = (child - 1) / 2;
		while (child > 0)
		{
			//if (_con[child] > _con[parent])
			//if (_con[parent] < _con[child])
			if (com(_con[parent], _con[child]))
			{
				std::swap(_con[child], _con[parent]);
				child = parent;
				parent = (child - 1) / 2;
			}
			else
			{
				break;
			}
		}
	}

使用

int main()
{
    int a[]={3,7,8,3,1,2,6,5};
    chy::priority_queue<int> qq( a,a+sizeof(a)/sizeof(a[0]) );//用迭代器构造的
    chy::priority_queue<int,vector<int>,greater<int> > Qq(a,a+sizeof(a)/sizeof(a[0]));
    //用great必须这么写
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值