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

#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;
}

發佈了51 篇原創文章 · 獲贊 3 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章