#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;
}
priority_queue (仿sgi stl) 純手打 累死TMD
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.