第四章:优先级队列和仿函数

一、认识优先级队列:

1.1什么是优先级队列?

  • 优先级队列(Priority Queue)是一种特殊的队列数据结构,每个元素都有一个优先级,元素按照优先级顺序进行处理,而不是按照插入顺序。
  • 在C++中,priority_queue默认是一个最大堆,即优先级最高的元素(值最大)会首先出队。也可以通过自定义比较器来实现最小堆或其他优先级顺序。
  • 优先级队列使用要包含头文件<queue>。

1.2优先级队列的默认容器:

  • 在C++中,priority_queue是一个容器适配器,它可以使用不同的底层容器来存储数据。默认情况下,priority_queue使用vector作为底层容器,但也可以使用其他支持随机访问的序列容器,如deque。
  • 支持迭代器区间构造。

1.3接口:

 二、模拟实现优先级队列:

2.1模板参数:

  • 优先级队列是容器适配器,最合适的容器是vector。
	template<class T, class Container = vector<T>>
	class priority_queue
	{}

2.2私有成员:

	private:
		Container _con;

2.3插入和向上调整:

  •  尾插后向上调整尾部元素到合适的位置处
		void push(const T& x)
		{
			_con.push_back(x);//尾插
			adjust_up(_con.size() - 1);//向上调整最后一个数据,size()-1就是最后一个数据的地址
		}
		void adjust_up(size_t child)
		{
			size_t parent = (child - 1) / 2;//计算得到父节点的下标
			while (child > 0)//当子节点下标不为0时,持续循环
			{
				if (_con[child] > _con[parent])//如果父节点值小于子节点
				{
					swap(_con[child], _con[parent]);//交换两个节点处的值
					child = parent;//调整指向父子结点的指向,
					parent = (child - 1) / 2;
				}
				else//如果父节点值小于子节点值,跳出循环
					break;
			}
		}

2.4删除和向下调整:

  • 删除就是删除最大的元素,交换首尾节点的值,从树根处向下调整即可
		void pop()
		{
			swap(_con[0], _con[_con.size() - 1]);//交换二叉树首尾两个元素
			_con.pop_back();//将尾元素删去,相当于删掉最大的元素
			adjust_down(0);//根节点处向下调整
		}
		void adjust_down(size_t parent)
		{
			size_t child = parent * 2 + 1;//计算出子节点下标,默认左子节点
			while (child < _con.size())//如果有子节点
			{
				if (child + 1 < _con.size() && _con[child] < _con[child + 1])//如果存在右子节点,且右节点值大于左节点
				{
					child++;//将要处理的节点变为右节点
				}
				if (_con[parent] < _con[child])//如果父节点值小于子节点值
				{
					swap(_con[parent], _con[child]);//交换两个节点值
					parent = child;//修改两个节点的指向
					child = parent * 2 + 1;
				}
				else
					break;//如果不小于,跳出循环
			}
		}

2.5其他函数:

  • 直接调用容器的函数即可。
		bool empty()
		{
			return _con.empty();
		}

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

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

三、仿函数“

3.1是上面仿函数?

  • 仿函数(Functor)是一个类或结构体,它重载了函数调用运算符 operator()。这使得仿函数对象可以像函数一样被调用。
  • 仿函数通常用于提供自定义的操作或比较方式,它们可以作为参数传递给算法或容器,从而定制它们的行为。
  • 仿函数在功能上可以代替函数指针。

3.2实例演示:

  • 以下是一个仿函数,当需要比较两个T类型时,可以匿名创建一个对象调用他的operator();
template<class T>
struct less
{
    bool operator()(T a, T b) const
    {
        return a < b; // 自定义比较规则
    }
};
template<class T>
struct more
{
    bool operator()(T a, T b) const
    {
        return a > b; // 自定义比较规则
    }
};
  • 当我们写一个比较函数compare时,就不用多写一份判断了。
int compare(int a,int b)
{
    return less(a,b);//return more(a,b);
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

S+叮当猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值