当前位置: 首页 > news >正文

青岛开发区 网站建设百度权重网站排名

青岛开发区 网站建设,百度权重网站排名,wordpress打赏,俄语网站模板👦个人主页:Weraphael ✍🏻作者简介:目前学习C和算法 ✈️专栏:C航路 🐋 希望大家多多支持,咱一起进步!😁 如果文章对你有帮助的话 欢迎 评论💬 点赞&#x1…

在这里插入图片描述

👦个人主页:@Weraphael
✍🏻作者简介:目前学习C++和算法
✈️专栏:C++航路
🐋 希望大家多多支持,咱一起进步!😁
如果文章对你有帮助的话
欢迎 评论💬 点赞👍🏻 收藏 📂 加关注✨


目录

  • 一、priority_queue的介绍
  • 二、为什么priority_queue不像stack和queue一样使用deque作为其底层存储数据的容器呢
  • 三、priority_queue的常见操作
  • 四、模拟实现priority_queue
      • 4.1 构造函数
      • 4.2 删除堆顶元素pop
      • 4.3 插入push
      • 4.4 获取堆顶元素top
      • 4.5 判断是否为空empty
      • 4.6 获取个数大小size
  • 五、仿函数
      • 5.1 什么是仿函数
      • 5.2 实现priority_queue的仿函数

一、priority_queue的介绍

在这里插入图片描述

  • priority_queue是一个容器适配器,默认使用vector作为其底层存储数据的容器
  • priority_queuevector上使用了堆heap的算法将vector中元素构造堆的结构,因此,priority_queue就是堆默认情况下是大堆。(如何构造成小堆在【仿函数】会讲解到)

二、为什么priority_queue不像stack和queue一样使用deque作为其底层存储数据的容器呢

  1. 这是因为vector在插入和删除元素时具有较好的性能表现。

在堆中插入新元素时,为了保持堆的特性(大堆/小堆)。则需要通过不断地比较和移动元素来完成。vector作为一个连续的内存块,可以更高效地进行元素的插入操作。

相比之下,deque在插入和删除操作时,需要考虑在数组的两端进行操作(头部和尾部),并且要进行元素的移动操作,使得时间复杂度稍高于vector

尽管deque在头部和尾部插入/删除操作上有一些优势,但对于优先级队列这种需要频繁访问和处理最高优先级元素的场景来说,vector更加合适

  1. 弹出pop元素:若要得到堆顶的元素,需要将堆顶元素与最后一个元素交换,并重新调整堆使其满足堆的性质。同样,由于vector是连续存储的,这个操作也可以更高效地进行。

  2. deque的存储空间不是连续的,因此在使用时需要更多的空间,可能会导致空间的浪费。

三、priority_queue的常见操作

在这里插入图片描述

#include <iostream>
#include <queue>
using namespace std;// priority_queue的常见操作int main()
{// 默认是大堆priority_queue<int> pq;pq.push(3);pq.push(5);pq.push(1);pq.push(4);pq.push(0);while (!pq.empty()){cout << pq.top() << ' ';pq.pop();}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

注意:优先级队列也是不支持迭代器遍历的!!!

四、模拟实现priority_queue

4.1 构造函数

namespace wj
{template<class T, class container = vector<T>>class priority_queue{	private:void AdjustDown(int parent){// 建大堆// 找左右孩子大的size_t child = parent * 2 + 1;while (child < _con.size()){// 保证右孩子存在if (child + 1 < _con.size() && _con[child + 1] > _con[child]) {++child;}if (_con[child] > _con[parent]){swap(_con[child], _con[parent]);parent = child;child = parent * 2 + 1;}else{break;}}}public:// 无参默认构造priority_queue(){}// 带区间的构造template<class InputIterator>priority_queue(InputIterator first, InputIterator last){// 插入数据while (first != last){_con.push_back(*first);++first;}//  建堆操作 (默认是大堆) for (int i = (_con.size() - 1 - 1) / 2; i >= 0; i--){AdjustDown(i);}}private:container _con;};
}

插入一个数据,由于还要保持大堆的性质,如果尾插的结点要比其父结点大,就要进行 向上调整

参考博客:点击跳转

4.2 删除堆顶元素pop

void pop()
{// 头尾结点交换,删除swap(_con[0], _con[_con.size() - 1]);_con.pop_back();// 然后再建堆AdjustDown(0);
}

4.3 插入push

void push(const T& val)
{// 尾部插入一个_con.push_back(val);// 再建堆AdjustUp(_con.size() - 1);
}

4.4 获取堆顶元素top

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

4.5 判断是否为空empty

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

4.6 获取个数大小size

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

五、仿函数

5.1 什么是仿函数

  • 仿函数(函数对象)是一种能够被像函数一样调用的对象。它通常是一个类或者结构体,重载了函数调用运算符 operator(),通过重载这个运算符,我们可以将对象当作函数来使用,实现了类似函数的行为。

  • 仿函数可以有自己的状态和成员变量,因此可以在多次调用中保持状态。它可以接受参数,并返回一个值。

例如,定义一个加法仿函数可以这样实现:

struct Add 
{int operator()(const int a, const int b) const {return a + b;}
};int main() 
{Add add;int result = add(3, 5);  // 调用仿函数cout << "add(3, 5) = " << result << endl;return 0;
}

在上面的例子中,Add是一个仿函数,它重载了函数调用运算符 operator(),使得add对象可以像函数一样被调用。通过add(3, 5),我们可以得到结果8

  • 在C++ 中,仿函数是一种灵活且强大的编程工具,常常用于算法和标准库中的函数对象。

在这里插入图片描述

就比如说sort函数,默认排的是升序

#include <iostream>
#include <algorithm>
using namespace std;int main()
{int arr[] = { 5,1,4,2,0,3 };int arrSize = sizeof(arr) / sizeof(arr[0]);// less<int> 默认可以不写sort(arr, arr + arrSize, less<int>());for (int i = 0; i < arrSize; i++){cout << arr[i] << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

less是库里提供的,其作用就是用于小于不等式比较的函数对象类

在这里插入图片描述

那么如果想排降序,可以将less替换成greater,这也是库里提供的,其作用是用于大于不等式比较的函数对象类

在这里插入图片描述

#include <iostream>
#include <algorithm>
using namespace std;int main()
{int arr[] = { 5,1,4,2,0,3 };int arrSize = sizeof(arr) / sizeof(arr[0]);// less<int> 默认可以不写sort(arr, arr + arrSize, greater<int>());for (int i = 0; i < arrSize; i++){cout << arr[i] << ' ';}cout << endl;return 0;
}

【输出结果】

在这里插入图片描述

5.2 实现priority_queue的仿函数

namespace wj
{template<class T, class container = vector<T>, class Compare = less<T>>class priority_queue{private:void AdjustDown(int parent){Compare com;// 建大堆// 找左右孩子大的size_t child = parent * 2 + 1;while (child < _con.size()){if (child + 1 < _con.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 AdjustUp(int child){Compare com;int parent = (child - 1) / 2;while (child > 0){if (com(_con[parent], _con[child])){swap(_con[child], _con[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}}public:// 无参默认构造priority_queue(){}// 带区间的构造template<class InputIterator>priority_queue(InputIterator first, InputIterator last){// 插入数据while (first != last){_con.push_back(*first);++first;}//  建堆操作 (默认是大堆) for (int i = (_con.size() - 1 - 1) / 2; i >= 0; i--){AdjustDown(i);}}void pop(){// 头尾结点交换,删除swap(_con[0], _con[_con.size() - 1]);_con.pop_back();// 然后再建堆AdjustDown(0);}void push(const T& val){// 尾部插入一个_con.push_back(val);// 再建堆AdjustUp(_con.size() - 1);}const T& top(){return _con[0];}bool empty(){return _con.empty();}size_t size(){return  _con.size();}private:container _con;};
}

注意:如果在priority_queue中放自定义类型的数据,用户需要在自定义类型中提供>或者<的重载。

namespace wj
{template<class T, class container = vector<T>, class Compare = less<T>>class priority_queue{private:void AdjustDown(int parent){Compare com;// 建大堆// 找左右孩子大的size_t child = parent * 2 + 1;while (child < _con.size()){// 改动if (child + 1 < _con.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 AdjustUp(int child){Compare com;int parent = (child - 1) / 2;while (child > 0){if (com(_con[parent], _con[child])){swap(_con[child], _con[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}}public:// 无参默认构造priority_queue(){}// 带区间的构造template<class InputIterator>priority_queue(InputIterator first, InputIterator last){// 插入数据while (first != last){_con.push_back(*first);++first;}//  建堆操作 (默认是大堆) for (int i = (_con.size() - 1 - 1) / 2; i >= 0; i--){AdjustDown(i);}}void pop(){// 头尾结点交换,删除swap(_con[0], _con[_con.size() - 1]);_con.pop_back();// 然后再建堆AdjustDown(0);}void push(const T& val){// 尾部插入一个_con.push_back(val);// 再建堆AdjustUp(_con.size() - 1);}const T& top(){return _con[0];}bool empty(){return _con.empty();}size_t size(){return  _con.size();}private:container _con;};// 日期类class Date{public:Date(int year = 1900, int month = 1, int day = 1): _year(year), _month(month), _day(day){}bool operator<(const Date& d)const{return (_year < d._year) ||(_year == d._year && _month < d._month) ||(_year == d._year && _month == d._month && _day < d._day);}bool operator>(const Date& d)const{return (_year > d._year) ||(_year == d._year && _month > d._month) ||(_year == d._year && _month == d._month && _day > d._day);}friend ostream& operator<<(ostream& _cout, const Date& d);private:int _year;int _month;int _day;};ostream& operator<<(ostream& _cout, const Date& d){_cout << d._year << "-" << d._month << "-" << d._day;return _cout;}
}
http://www.shuangfujiaoyu.com/news/24953.html

相关文章:

  • 张家港做网站哪家好9个成功的市场营销案例
  • 西安注册公司在哪个网站系统郑州seo排名哪有
  • 上海网络企业优化公司东莞网站建设seo
  • 体育网站建设视频自动seo系统
  • 做直播网站需要学什么淘宝怎么优化关键词排名
  • 廊坊建手机网站外包接单平台
  • 做企业网站设计价格是多少网络营销常见术语
  • 网站怎么做组织图国际新闻今日头条
  • 成都三合一网站建设广州网络推广万企在线
  • 金水郑州网站建设seo搜索引擎优化薪资
  • 做企业网站的代码网页制作学习
  • 软件开发工资一般多少深圳网络推广优化方案
  • word怎么做网站链接爱奇艺科技有限公司
  • 做微商去哪些社交网站百度广告推广怎么收费了
  • 网站后台 不能删除文章可以免费打开网站的软件下载
  • 程序员 创业做网站深圳整站全网推广
  • 淄博建设企业网站天天网站
  • 学生作业制作网站黑帽seo优化推广
  • 福州建设网站效果图网络推广与网络营销的区别
  • wordpress制作商城厦门seo网络推广
  • 建湖做网站的公司今日小说百度搜索风云榜
  • 网站建设公司该怎么销售优化seo招聘
  • 4s店网站建设做好网络推广
  • 广州市招标采购网官网新乡seo推广
  • 网站生成海报功能怎么做的市场营销策划案例经典大全
  • 重庆微信网站开今日头条搜索优化怎么做
  • 诸城网站建设定制正规优化公司哪家好
  • h5响应式网站是什么意思百度一下官网首页百度一下百度
  • 织梦网站英文版怎么做培训机构招生方案
  • 长沙网站建设哪家强搜索排名广告营销怎么做