priority_queue (仿sgi stl) 纯手打 累死TMD

本文详细介绍了C++中优先队列的实现原理及使用方法,包括内部模板函数的作用和优先队列类的构造、操作等核心内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <iostream>
#include <vector>
//#include <iterator> 
#include <xutility> // 内含 _Val_type _Dist_type
#include <functional> // 内含 less 函数对象
using namespace std;

template <typename RandomAccessIterator, typename Distance, typename T>
void __push_heap(RandomAccessIterator first, Distance holeIndex, Distance topIndex, T value) 
{
	Distance parent = (holeIndex - 1) / 2;

	while (holeIndex > topIndex && *(first+parent) < value)
	{
		*(first + holeIndex) = *(first + parent);
		holeIndex = parent;
		parent = (holeIndex - 1) / 2;
	}
	*(first + holeIndex) = value;
}

template <typename RandomAccessIterator, typename Distance, typename T>
inline void __push_heap_aux(RandomAccessIterator first, RandomAccessIterator last, Distance*, T*)
{
	__push_heap(first, Distance(last-first-1), Distance(0), T(*(last-1)));
}

template <typename RandomAccessIterator>
inline void push_heap(RandomAccessIterator first, RandomAccessIterator last) // 再调用这个函数前 value已经在容器底端
{
	__push_heap_aux(first, last, _Dist_type(first), _Val_type(first)); // sgi里面是 distance_type 和 value_type VS下是用的那俩 
}

template <typename RandomAccessIterator, typename Distance, typename T, typename Compare>
void __push_heap(RandomAccessIterator first, Distance holeIndex, Distance topIndex, T value, Compare comp)
{
	Distance parent = (holeIndex - 1) / 2;
	while (holeIndex > topIndex && comp(*(first+parent), value))
	{
		*(first + holeIndex) = *(first + parent);
		holeIndex = parent;
		parent = (holeIndex - 1) / 2;
	}
	*(first + holeIndex) = value;
}

template <typename RandomAccessIterator, typename Compare, typename Distance, typename T>
inline void __push_heap_aux(RandomAccessIterator first, RandomAccessIterator last, Compare comp, Distance*, T*)
{
	__push_heap(first, Distance((last-first)-1), Distance(0), T(*(last-1)), comp);
}

template <typename RandomAccessIterator, typename Compare>
inline void push_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp)
{
	__push_heap_aux(first, last, comp, _Dist_type(first), _Val_type(first));
}

template <typename RandomAccessIterator, typename Distance, typename T>
void __adjust_heap(RandomAccessIterator first, Distance holeIndex, Distance len, T value)
{
	Distance topIndex = holeIndex;
	Distance secondChild = 2 * holeIndex + 2;

	while (secondChild < len)
	{
		if (*(first+secondChild) < *(first+(secondChild-1)))
		{
			secondChild--;
		}
		*(first + holeIndex) = *(first + secondChild);
		holeIndex = secondChild;
		secondChild = 2(secondChild + 1);
	}
	if (secondChild == len)
	{
		*(first + holeIndex) = *(first + (secondChild - 1));
		holeIndex = secondChild - 1;
	} 

	__push_heap(first, holeIndex, topIndex, value);
}

template <typename RandomAccessIterator, typename T, typename Distance>
inline void __pop_heap(RandomAccessIterator first, RandomAccessIterator last, RandomAccessIterator result, T value, Distance*)
{
	*result = *first;
	__adjust_heap(first, Distance(0), Distance(last-first), value);

}

template <typename RandomAccessIterator, typename T>
inline void __pop_heap_aux(RandomAccessIterator first, RandomAccessIterator last, T*)
{
	__pop_heap(first, last-1, last-1, T(*(last-1), _Dist_type(first)))
}

template <typename RandomAccessIterator>
inline void pop_heap(RandomAccessIterator first, RandomAccessIterator last)
{
	__pop_heap_aux(first, last, _Val_type(first));
}

template <typename RandomAccessIterator, typename Distance, typename T, typename Compare>
void __adjust_heap(RandomAccessIterator first, Distance holeIndex, Distance len, T value, Compare comp)
{
	Distance topIndex = holeIndex;
	Distance secondChild = 2 * holeIndex + 2;

	while (secondChild < len)
	{
		if (comp(*(first + secondChild), *(first+ (secondChild - 1) )))
		{
			secondChild--;
		}
		*(first + holeIndex) = *(first + secondChild);
		holeIndex = secondChild;
		secondChild = 2 * (secondChild + 1);
	}
	if (secondChild == len)
	{
		*(first + holeIndex) = *(first + (secondChild - 1));
		holeIndex = secondChild - 1;
	}
	__push_heap(first, holeIndex, topIndex, value, comp);
}

template <typename RandomAccessIterator, typename T, typename Compare, typename Distance>
inline void __pop_heap(RandomAccessIterator first, RandomAccessIterator last, RandomAccessIterator result, T value, Compare comp, Distance*)
{
	*result = *first;
	__adjust_heap(first, Distance(0), Distance(last-first), value, comp);
}

template <typename RandomAccessIterator, typename T, typename Compare>
inline void __pop_heap_aux(RandomAccessIterator first, RandomAccessIterator last, T*, Compare comp)
{
	__pop_heap(first, last-1, last-1, T(*(last-1)), comp, _Dist_type(first));
}

template <typename RandomAccessIterator, typename Compare>
inline void pop_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp)
{
	__pop_heap_aux(first, last, _Val_type(first), comp);
}

template <typename RandomAccessIterator, typename T, typename Distance>
void __make_heap(RandomAccessIterator first, RandomAccessIterator last, T*)
{
	if (last - first < 2) return;
	Distance len = last - first;
	Distance parent = (len - 2) / 2;

	while (true)
	{
		__adjust_heap(first, parent, len, T(*(first+parent)));
		if (parent == 0) return;
		parent--;
	}
}

template <typename RandomAccessIterator>
inline void make_heap(RandomAccessIterator first, RandomAccessIterator last)
{
	__make_heap(first, last, _Val_type(first), _Dist_type(first));
}

template <typename RandomAccessIterator, typename Distance, typename T, typename Compare>
void __make_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp, T*, Distance*)
{
	if (last-first < 2) return;
	Distance len = last - first;
	Distance parent = (len - 2) / 2;

	while (true)
	{
		__adjust_heap(first, parent, len, T(*(first+parent)), comp);
		if (parent == 0) return;
		parent--;
	}
}

template <typename RandomAccessIterator, typename Compare>
inline void make_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp)
{
	__make_heap(first, last, comp, _Val_type(first), _Dist_type(first));
}

template <typename RandomAccessIterator>
void sort_heap(RandomAccessIterator first, RandomAccessIterator last) 
{
	while (last - frist > 1)
	{
		pop_heap(first, last--); 
	}
}

template <typename RandomAccessIterator, typename Compare>
void sort_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp)
{
	while (last - first > 1)
	{
		pop_heap(first, last--, comp);
	}
}

// 以下为最大优先队列

template <typename T, typename Sequence = vector<T>, typename Compare = less<Sequence::value_type>>
class priority_queue
{
public:
	typedef typename Sequence::value_type value_type;
	typedef typename Sequence::size_type size_type;
	typedef typename Sequence::reference reference;
	typedef typename Sequence::const_reference const_reference;

protected:
	Sequence c;
	Compare comp;

public:
	priority_queue() : c() {}
	explicit priority_queue(const Compare &x) : c(), comp(x) {} // 用户可以指定自己的优先级决策函数对象

	template <typename InputIterator>
	priority_queue(InputIterator first, InputIterator last, const Compare &x) : c(first, last), comp(x)
	{
		make_heap(c.begin(), c.end(), comp);
	}
		
	template <typename InputIterator>
	priority_queue(InputIterator first, InputIterator last) : c(first, last)
	{
		make_heap(c.begin(), c.end(), comp);
	}

	priority_queue(const value_type* first, const value_type* last,
		const Compare& x) : c(first, last), comp(x)
	{
		make_heap(c.begin(), c.end(), comp);
	}
	priority_queue(const value_type* first, const value_type* last)
		: c(first, last) 
	{
		make_heap(c.begin(), c.end(), comp);
	}

	bool empty() const { return c.empty();}
	size_type size() const { return c.size(); }
	const_reference top() const { return c.front(); }

	void push(const value_type &x)
	{
		c.push_back(x);
		push_heaap(c.begin(), c.end(), comp);
	}

	void pop()
	{
		pop_heap(c.begin(), c.end(), comp);
		c.pop_back();
	}
};

int main()
{
	int ia[9] = {0,1,2,3,4,8,9,3,5};

	priority_queue<int> ipq(ia, ia+9);
	cout << "size = " << ipq.size() << endl;
	for (size_t i = 0; i < ipq.size(); ++i)
		cout << ipq.top() << " ";
	cout << endl;

	while (!ipq.empty())
	{
		cout << ipq.top() << " ";
		ipq.pop();
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值