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

怎么网站做二维码宁德市人民医院

怎么网站做二维码,宁德市人民医院,黄岛网站建设,玉器珠宝做网站目录 priority_queue的作用priority_queue的接口构造函数emptysizetoppushpopswap priority_queue的实现仿函数(函数对象)是什么?向上调整算法(adjustup)向下调整算法(adjustdown)迭代器构造pus…

目录

  • priority_queue的作用
  • priority_queue的接口
    • 构造函数
    • empty
    • size
    • top
    • push
    • pop
    • swap
  • priority_queue的实现
    • 仿函数(函数对象)是什么?
    • 向上调整算法(adjustup)
    • 向下调整算法(adjustdown)
    • 迭代器构造
    • push
    • pop

priority_queue的作用

priority_queue翻译过来就是优先级队列,是stl提供的一个容器适配器,也就是我们数据结构中学到的栈,是一种常用的数据结构,特点是利用类似二叉树的结构让父节点元素比子节点大,从而使对顶元素最大(小)。

priority_queue的接口

构造函数

explicit priority_queue (const Compare& comp = Compare(),const Container& ctnr = Container());
template <class InputIterator>priority_queue (InputIterator first, InputIterator last,const Compare& comp = Compare(),const Container& ctnr = Container());

可以用默认构造和迭代器构造,支持指定容器和仿函数对象。

empty

bool empty() const;

堆的判空。

size

size_type size() const;

返回堆的元素数。

top

const value_type& top() const;

返回堆顶元素。

push

void push (const value_type& val);

入堆。

pop

void pop();

出对顶的元素。

swap

void swap (priority_queue& x) noexcept (/*see below*/);

priority_queue自己的交换函数。

priority_queue的实现

#include<iostream>#include<vector>using namespace std;namespace jiunian
{template<class T, class container = vector<T>, class compare = less<T>>class priority_queue{public:typedef priority_queue<T, container> Self;priority_queue(){}template<class Iterator>priority_queue(Iterator begin, Iterator end){Iterator cur = begin;while (cur != end) con.push_back(*(cur++));int pos = size() / 2 - 1;while (pos >= 0) adjustdown(pos--);}bool empty() const{return con.empty();}size_t size() const{return con.size();}const T& top() const{return con.front();}void push(const T& val){con.push_back(val);adjustup(con.size() - 1);}void pop(){std::swap(con.front(), con.back());con.pop_back();adjustdown(0);}void swap(priority_queue& x){con.swap(x.con);}Self operator=(Self x){con = x.con;comp = x.comp;return *this;}private:void adjustdown(int pos)//向下调整{int parent = pos;int child = parent * 2 + 1;if (child + 1 < con.size() && comp(con[child] , con[child + 1])) ++child;while(child < con.size()){if (comp(con[parent], con[child])){std::swap(con[child], con[parent]);parent = child;child = parent * 2 + 1;if (child + 1 < con.size() && comp(con[child], con[child + 1])) ++child;}else{break;}}}void adjustup(int pos)//向上调整{int child = pos;int parent = (child + 1) / 2 - 1;while (parent >= 0){if (comp(con[parent], con[child])){std::swap(con[child], con[parent]);child = parent;parent = (child + 1) / 2 - 1;}else{break;}}}container con;compare comp;};
}

仿函数(函数对象)是什么?

仿函数又称函数对象,是指其本质虽然是对象,但是用起来就像函数一样,一个简单的仿函数张下面这样:

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

仿函数通过重载()运算符使其使用起来就像函数一样,依旧一上面这个仿函数为例,它的用法如下

	compareruler<int> com;int a = 0;int b = 1;cout << com(a, b) << endl;

不看上面的对象初始化就会误以为com是函数了。这就是仿函数,那说了这么多,仿函数有什么用呢?学习过模板的都知道,c++提倡泛型编程,即一段代码多种用途,通过模板与模板实例化使一段代码生成多段代码,鼓励用户自定义,提高编程效率。而仿函数更是使泛型编程更进一步,仿函数可以自定义模板编程中的策略模式,使用户使用起来更加自由,比如在堆的实现过程中就可以自定义两数之间的比较交换规则实现大堆小堆的切换,这也是我提前介绍一下仿函数的原因。

向上调整算法(adjustup)

void adjustup(int pos)//向上调整
{int child = pos;int parent = (child + 1) / 2 - 1;while (parent >= 0){if (comp(con[parent], con[child])){std::swap(con[child], con[parent]);child = parent;parent = (child + 1) / 2 - 1;}else{break;}}
}

向上调整算法是堆的核心算法之一,其原理是将指定元素通过与其父结点比较,若不符合当前堆的排列规则(大堆小堆)就交换,符合就停止,不断地循环这个过程直到根节点,从而将指定元素排到合适的位置。具体的实现过程就是先指定结点,将指定的结点视为子节点,算出字结点的父节点,将两者进行比较,比较逻辑由仿函数给出。若仿函数返回true就交换,之后将换完的父节点视为子节点,再次计算父节点不断循环;若仿函数返回false就说明到合适的位置了,停止循环即可。过程中要时刻注意越界问题。

向下调整算法(adjustdown)

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

向上调整算法也是堆的核心算法之一,其原理是将指定元素通过与其最大的(大堆,小堆相反)子结点比较,若不符合当前堆的排列规则(大堆小堆)就交换,符合就停止,不断地循环这个过程直到不能向下为止,从而将指定元素排到合适的位置。具体的实现过程就是先指定结点,将指定的结点视为父节点,算出父结点的子节点中最大的一个,将两者进行比较,比较逻辑由仿函数给出。若仿函数返回true就交换,之后将换完的子节点视为父节点,再次计算子节点不断循环;若仿函数返回false就说明到合适的位置了,停止循环即可。过程中要时刻注意越界问题。

迭代器构造

		template<class Iterator>priority_queue(Iterator begin, Iterator end){Iterator cur = begin;while (cur != end) con.push_back(*(cur++));int pos = size() / 2 - 1;while (pos >= 0) adjustdown(pos--);}

迭代其构造的思路有两种,一种是先全部拷进堆中,再排序,第二种是一个个push进去。效率差不多,我使用的第一种,因为难写一点,使用第一种写法需要注意使用向下调整算法比向上调整更优秀。为什么呢?使用向上调整算法就要从最上方也就是根节点开始把推遍历一遍才行,而使用向下调整算法则反之,要从堆的最下面的最后一个元素开始遍历对一遍。其中向上和向下的算法中单趟的时间复杂度都是logN,这样看来两者都是一样的,但是注意,两者都是有优化的空间的。当使用向上调整算法时,根节点因为没有父结点所以没有比的必要,可以优化掉一个;而使用向下调整算法时最下面一排的元素(满二叉树就是最下面一排,不是满二叉树就是最下面一排加最下面第二排部分,反正就是没有子节点的结点也就是叶子节点)因为没有子节点所以也没有比的必要,可以优化掉整整一排,要知道最后一排的结点数占了二叉树差不多一半,优化巨大,所以要用向下调整算法从最后一个有子结点的结点开始遍历,找这个结点的方式也很简单,最后一个有子结点的结点就是最后一个元素的父结点。

push

void push(const T& val)
{con.push_back(val);adjustup(con.size() - 1);
}

先入到容器的结尾,再用向上调整算法跳到合适的位置就行。

pop

void pop()
{std::swap(con.front(), con.back());con.pop_back();adjustdown(0);
}

由于我们这的堆是依靠容器中的位置模拟的二叉树,所以对于相对位置有着强逻辑,堆顶的元素不能直接头删,我们先将堆顶元素与最后一个元素交换,之后尾删,相当于删除堆顶在找了个替位的,之后对堆顶这个替位的使用向下调整算法调到合适的位置就行了。

由于priority_queue本质是一个容器适配器,其他的函数就只是对适配器接口的一些封装了,很简单,这里不过多赘述。

http://www.dtcms.com/wzjs/274502.html

相关文章:

  • 网站建设 英文百度推广好做吗
  • 什么网站系统好百度竞价排名费用
  • 都有什么公司需要网站建设网站的网络推广
  • 做网站 用什么建站软件好企业产品推广运营公司
  • wordpress外贸发布接口网站seo收录
  • 请兼职做企业网站设计怎么收费搜索引擎seo是什么意思
  • 网站的页面设计什么是网络营销?
  • 个人网站网站网站建设制作教程
  • 长沙做公司网站南昌seo网站管理
  • wordpress配置ip访问公司网站seo公司
  • 公司建设网站费用怎么记账软文广告是什么意思
  • 做学习交流网站营销广告
  • 个人博客网站模板素材中文搜索引擎排名
  • 荥阳市建设局网站搜索引擎优化方法包括
  • 庆阳市镇原县疫情最新情况网站页面优化内容包括哪些
  • 怎么看别人网站是哪里做的网站营销推广有哪些
  • 什么网站上做推广百度百家号官网
  • 网站收录下降原因怎么做网站广告
  • 个人可以采集视频做网站吗成都seo优化
  • 东莞网站建设设商丘 峰少 seo博客
  • 一级a做爰片免费网站丶网络营销价格策略有哪些
  • 推广自己的网站需要怎么做中国十大软件外包公司
  • 静态wordpress ajaxseo管理是什么
  • 给工厂做英文外贸网站seo搜索引擎优化内容
  • 宁波优化网站排名软件嘉兴seo网络推广
  • 帮企业建网站步骤社群运营的经典案例
  • 山东济宁网站建设设计杭州优化公司哪家好
  • 怎么用php做网站优化排名案例
  • 国外物流公司网站模板最好的bt种子搜索引擎
  • pacharm做腾讯视频网站打开百度网页版