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

浙江网站改版设计公司产品推广运营方案

浙江网站改版设计公司,产品推广运营方案,免费域名注册发卡网,wordpress csv导出### 容器适配器是将容器转换到其他容器自身不方便使用的地方,但是就容器适配器其本身还是包装的容器,所以这个类模板中各个接口的实现都是调用的容器的接口,因为容器适配器可能适配多个容器,所以这个类模板的模板参数中有一个参数…

###

容器适配器是将容器转换到其他容器自身不方便使用的地方,但是就容器适配器其本身还是包装的容器,所以这个类模板中各个接口的实现都是调用的容器的接口,因为容器适配器可能适配多个容器,所以这个类模板的模板参数中有一个参数是代表容器类型的,方便传参过来能及时改变;

一、stack的模拟

这是这个类模板的模板,那么我们也模拟这样实现,首先解读,T是stack里面存放的数据类型,Container是stack里面包装的容器的类型,默认是deque,这是因为deque这个容器不仅兼顾了vector和list的基本接口,并且deque相比于vector不需要浪费过多空间、头删头插的效率高,相比于list的缓存利用率更高,这个和deque的底层结构有关;

###stack实现的代码:

#pragma once
#include<deque>
#include<list>
#include<vector>
using namespace std;
namespace S
{template<class T,class Container = deque<T>>class Stack{public:Stack()//调用Container的默认构造函数{}bool empty()const{return _con.empty();}size_t size()const{return _con.size();}const T& top()const{return _con.back();}void push(const T& val = T()){_con.push_back(val);}void pop(){_con.pop_back();}private:Container _con;};
}

首先stack对于vector、list、deque都能作为它们的适配器,所以头文件包含了这几个容器;

其次看到这个模板类的成员变量,是一个Container,代表容器类型,这个容器类型默认为deque,用这个类型去定义一个容器作为stack这个适配器的成员变量,那么在实现stack的接口时,就直接调用容器_con的接口;

###测试:

void test1()
{Stack<int> st;st.push(1);st.push(2);st.push(3);st.push(4);st.push(5);cout << "数据个数:" << st.size() << endl;cout << "是否为空:" << st.empty() << endl;cout <<"栈顶数据:"  << st.top() << endl;st.pop();cout << "数据个数:" << st.size() << endl;cout << "栈顶数据:" << st.top() << endl;
}

注意在源文件中测试时要包含实现stack的头文件,并且展开命名空间;

###运行结果:

二、queue的模拟

和stack大差不差,注意它不能作为vector的适配器,队列queue的头删(出队列)的接口要调用pop_front,而vector没有这个接口,所以不能;

###代码:

namespace Q
{template<class T ,class Container = deque<T>>class Queue{public:Queue(){}bool empty()const{return _con.empty();}size_t size()const{return _con.size();}const T& front()const{return _con.front();}const T& back()const{return _con.back();}void push(const T& val=T()){_con.push_back(val);}void pop(){_con.pop_front();}private:Container _con;};
}

 ###测试:

void test2()
{Queue<int> q;for (int i = 1; i <= 5; i++){q.push(i);}cout << "是否为空:" << q.empty() << endl;cout << "数据个数:" << q.size() << endl;cout << "队头数据:" << q.front() << endl;cout << "队尾数据:" << q.back() << endl;q.pop();//删除队头数据cout << "队头数据:" << q.front() << endl;
}

注意Queue<int> q;可以显示传它的容器类型,stack也是一样;

###运行结果:

三、priority_queue的模拟

这个是优先级队列,它的其他地方和queue一样,就是队头的元素一直是最大的或者是最小的,它的底层实现有堆的部分,大堆的堆顶也就是最大的,小堆的相反;所以在实现时涉及到堆的向上和向下调正的方法;

另外,我们要写一份类模板,这个类模板要求可以通过接收不同的模板参数来调正这个优先级队列是通过大堆实现的还是通过小堆实现的 ,这也是库里面的实现方法;也就是说,这个适配器的模板参数中要包含一个类型,这个类型实例化出来的对象作为适配器的成员变量(和_con类似),并且这个对象可以调用自己的函数来实现更大或者更小的比较,这里需要使用仿函数;

所谓的仿函数就是重载()的函数;

直接看实现的代码来解读

###代码实现:

namespace Q
{	
//仿函数重载()template<class T>class Less{public:bool operator()(T& x, T& y){return x < y;}};template<class T>class Greater{public:bool operator()(T& x, T& y){return x > y;}};template<class T,class Container =vector<T>,class Compare = Less<T>>class Priority_Queue{public:Priority_Queue(){}bool empty()const{return _con.empty();}size_t size()const{return _con.size();}const T& top()const{return _con[0];}void AdjustUp(){int child = _con.size() - 1;int parent = (child - 1) / 2;while (child >= 0){if(_com(_con[parent],_con[child])){swap(_con[parent], _con[child]);child = parent;parent = (child - 1) / 2;}else{break;}}}void push(const T& val = T()){_con.push_back(val);AdjustUp();//向上调正建堆}void AdjustDown(){int parent = 0;int 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[parent], _con[child]);parent = child;child = parent * 2 + 1;}else{break;}}}void pop(){assert(_con.size());swap(_con[0], _con[_con.size() - 1]);_con.pop_back();AdjustDown();}private:Container _con;Compare _com;//调用仿函数就直接_com(),相当于_com.operator();};}

第二个模板参数是vector这是因为里面有top的接口,而vector也有; 

首先看到类Less和Greater,里面有成员函数,都是重载的()的函数,也就是仿函数,包装成一个类是因为类可以作为类型传到模板参数中;

看到优先级队列的类模板的实现,第三个模板参数就是上面封装的类,这个默认是Less,在看到优先级队列的成员变量,除了我们已近知道的_con,还有一个_com,这是通过Less实例化出来的对象,这个对象可以直接在后面加上()来调用它自己的成员函数,那么就可以来进行比较了;

其他的接口很平常,看到push和pop的接口,首先push,要进行向上调整,里面使用_com(),就是比较父节点和子节点,父节点更小就和子节点交换,实现大堆;pop删除是先交换队头和队尾的数据再pop_back(),相当于删除了队头的节点,之后再进行向下调整,把次大的换到根节点处;

只有涉及到父节点和子节点比较大小时才用到_com(),这是因为这个函数的比较决定了是大堆还是小堆,当传Less<T>时就是大堆;传Greater时就是小堆(把更大的换到了子节点);

###测试:

void test3()
{Priority_Queue < int,vector<int>> pq;pq.push(1);pq.push(2);pq.push(3);pq.push(4);pq.push(5);pq.pop();cout << "是否为空:" << pq.empty() << endl;cout << "数据个数:" << pq.size() << endl;cout << "队头数据:" << pq.top() << endl;//也是堆顶数据
}

###运行结果

push走完 

 

pop走完

可以观察到这就是按照堆的规则调整的; 

http://www.hkea.cn/news/527699/

相关文章:

  • 贵卅省住房和城乡建设厅网站周口seo推广
  • 搭建flv视频网站seo工具查询
  • 企业展示网站 数据库设计模板自助建站
  • 房地产设计师上海seo网络优化
  • wordpress迁移打不开百度seo泛解析代发排名
  • 网站兼容性测试怎么做微信营销软件群发
  • wordpress如何设置内容页seo营销优化
  • 高端大气的网站制作南宁百度seo软件
  • 沙井营销型网站建设成人培训机构
  • 网站没有被百度收录搜索引擎排名优化公司
  • 手机网站转换小程序晋江怎么交换友情链接
  • 专业做网站的公司疫情放开最新消息今天
  • 不用写代码做网站软件长沙优化网站
  • o2o商城网站建设方案广告策划案优秀案例
  • 日照做网站的那家做的好百度网页链接
  • 建设云个人证件查询系统上海seo培训
  • 网站流量提供商杭州seo排名
  • 做装饰工程的在什么网站投标自建站
  • 地球人--一家只做信誉的网站帮忙推广的平台
  • 网站建设外包协议天津网站排名提升
  • 邯郸教育行业网站建设百度推广代理商查询
  • 政府网站有哪些网站seo最新优化方法
  • 做广告牌子seo外链工具
  • 微信页面设计网站兰州网络推广技术
  • 上门做网站搜狗站长工具
  • wordpress用户邮箱验证码百度seo搜索引擎优化培训
  • 360极速怎么屏蔽网站新闻热点大事件
  • 购物app开发价格表站长工具seo排名
  • 微餐饮网站建设营销型网站建设方案
  • 高端网站建设公司好不好2020国内搜索引擎排行榜