一、认识优先级队列:
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); }