模拟实现优先队列(仿函数的介绍)

自从学过数据结构中的堆以后每次想到大堆和小堆的代码就很头疼,最近学了优先队列(priority_queue)后,发现模拟实现优先队列正好用到了大堆小堆的知识,在这里记录一下加深记忆,同时方便以后查看。
模拟实现代码如下:

namespace my_space
{
	template<class T>
	struct less
	{
		bool operator()(const T& left, const T& right)
		{
			return left < right;
		}
	};
	//仿函数(仿函数就是一个类,在这个类里仅仅是重载了一个小括号,
	//仿函数只有一元仿函数和二元仿函数,根据参数个数确定)
	//仿函数就是用起来像函数的类
	template<class T>
	struct greater
	{
		bool operator()(const T& left, const T& right)
		{
			return left > right;
		}
	};
	template<class T, class Cont = vector<T>, class Pred = less<T> >
	class priority_queue
	{
	public:
		typedef T value_type;
		typedef size_t size_type;
		priority_queue()
		{}
		priority_queue(const value_type *first, const value_type *last)
		{
			while (first != last)
				c.push_back(*first++);
			int root = (c.size() - 1) / 2; //找到二叉树的最后面一个需要向下调的节点
			while (root >= 0)
				adjustdown(root--);
		}
		bool empty() const
		{
			return c.empty();
		}
		size_type size() const
		{
			return c.size();
		}
		value_type& top()
		{
			assert(!empty());
			return c.front();
		}
		const value_type& top() const
		{
			assert(!empty());
			return c.front();
		}
		void push(const value_type &x)
		{
			c.push_back(x);
			adjustup(c.size() - 1);
		}
		void pop()
		{
			std::swap(c.front(), c.back());
			c.pop_back();
			adjustdown(0);
		}
	protected:
		void adjustdown(int parent)
		{
			int child = 2 * parent + 1;
			while (child < c.size())
			{
				if (child + 1 < c.size() && comp(c[child], c[child + 1]))
					++child;
				if (comp(c[parent], c[child])) //-->comp.operator(c[parent], c[chid])
				{
					std::swap(c[parent], c[child]);
					parent = child;
					child = 2 * parent + 1;
				}
				else
					break;
			}
		}
		void adjustup(int child)
		{
			int parent = (child - 1) / 2;
			while (child)
			{
				if (comp(c[parent], c[child]))
				{
					std::swap(c[parent], c[child]);
					child = parent;
					parent = (child - 1) / 2;
				}
				else
					break;
			}
		}
	private:
		Cont c;
		Pred comp;
	};
}

测试代码1:

int main()
{
	my_space::priority_queue<int> pq;
	pq.push(1);
	pq.push(7);
	pq.push(2);
	pq.push(3);
	pq.push(9);
	pq.push(4);
	pq.push(5);
	cout << pq.top() << endl;
	pq.pop();
	cout << pq.top() << endl;
	return 0;
}

测试代码2:

void main()
{
	int v[] = { 5, 7, 8, 2, 9, 3, 1, 0 };
	int n = sizeof(v) / sizeof(v[0]);
	my_space::priority_queue<int, vector<int>, my_space::greater<int> > pq(v, v + n);
	while (!pq.empty())
	{
		cout << "top = " << pq.top() << endl;
		pq.pop();
	}
}

我注意到在我们调用make_heap函数产生小堆时,调用方式如下:

#include <iostream>
#include <vector>
#include <functional>
int main()
{
	vector<int> v = { 5, 7, 9, 30, 4, 1, 0, 2 };
	for (const auto &e : v)
		cout << e << " ";
	cout << endl;
	//生成一个小堆
	make_heap(v.begin(), v.end(), greater<int>());
	for (const auto &e : v)
		cout << e << " ";
	cout << endl;
	return 0;
}

但是在优先队列生成小堆时如下:

my_space::priority_queue<int, vector<int>, my_space::greater<int> > pq(v, v + n);

他们的区别在于一个是greater<int>(),另一个是greater<int>,一个有小括号,另一个没有小括号,原因就是make_heap()是一个函数,所以参数需要传入一个临时对象,greater<int>()就是生成一个greater<int>类型的无名临时对象,而优先队列是一个模板类,我们传入的是一个类类型greater<int>,所以没有小括号。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
/数据结构课程设计--飞机场模拟--初始化及主程序 //舞动青春--张佳贵 //2009年6月 #include #include #include"Extended_queue.h" #include"Random.h" #include"Runway.h" #include"Plane.h" using namespace std; void run_idle(int time) { cout<<" "<<time<<":Runway is idle."<<endl; } //初始化程序 void initialize(int &end_time,int &queue_limit,double &arrival_rate,double &departure_rate){ cout<<"This is program simulates an airport with only one runway."<<endl <<"One plane can land or depart in each unit of time."<<endl; cout<<"Up to what number of planes can be waiting to land" <<" or take off at any time?"<>queue_limit; //输入用户期望的跑道最大容纳量 cout<<"How many uints of time will the simulation run?"<>end_time; bool acceptable; do { cout<<"Expected number of arrivals per uint time?"<>arrival_rate; cout<<"Expected number of departures per uint time?"<>departure_rate; if(arrival_rate<0.0||departure_rate<0.0) cerr<<"These rates must be nonnegative."<1.0) cerr<<"Safety Warning:This airport will become saturated."<<endl; }while(!acceptable); } //主程序 int main() { int end_time; int queue_limit; int flight_number=0; double arrival_rate; double departure_rate; initialize(end_time,queue_limit,arrival_rate,departure_rate); //初始化跑道信息 Random variable; //定义随机数变量 Runway small_airport(queue_limit); //判断当前发出请求的飞机是否应该被接受或拒绝 for(int current_time=0;current_time<end_time;current_time++){ int number_arrivals=variable.poisson(arrival_rate); for(int i=0;i<number_arrivals;i++){ Plane current_plane(flight_number++,current_time,arriving); if(small_airport.can_land(current_plane)!=success) current_plane.refuse(); } int number_departures=variable.poisson(departure_rate); for(int j=0;j<number_departures;j++){ Plane current_plane(fligh

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值