手打 模板二叉堆 支持随机访问

如有错请指正!谢谢!

#include <algorithm>
#include <vector>

using namespace std;

template<typename T, typename _Cont = vector<T>, typename _Comp = less<T>>
class heap
{
	public:
		typedef _Comp comparer;
		typedef _Cont container;
		typedef typename container::iterator iterator;
		typedef typename container::size_type size_type;
		
		T &at(int n) { return _M.at(n); }
		T &operator [](int n) { return this->at(n); }
		size_type size() { return _M.size(); }
		
		void push(T o)
		{
			_M.push_back(o);
			_adjust_up(--_M.end());
		}
		
		const T &top() { return this->at(0); }
		
		void pop()
		{
			swap(_M.front(), _M.back());
			_M.pop_back();
			_adjust_down(_M.begin());
		}
		
		iterator begin() { return _M.begin(); }
		iterator end() { return _M.end(); }
		
	private:
		comparer _c;
		container _M;
		
		void _adjust_up(iterator _idx)
		{
			while(_idx != _M.begin())
			{
				int _dis = distance(_M.begin(), _idx) + 1;
				iterator _pi = _M.begin() + (_dis >> 1) - 1;
				if(_c(*_pi, *_idx))
				{
					swap(*_pi, *_idx);
					_idx = _pi;
				}
				else break;
			}
		}
		
		void _adjust_down(iterator _idx)
		{
			int _dis = distance(_M.begin(), _idx) + 1;
			iterator _s = _M.begin() + (_dis << 1) - 1;
			while(_s < _M.end())
			{
				if(_s < --_M.end() && _c(*_s, *(_s + 1))) _s++;
				if(_c(*_idx, *_s))
				{
					swap(*_idx, *_s);
					_idx = _s;
					_dis = distance(_M.begin(), _idx) + 1;
					_s = _M.begin() + (_dis << 1) - 1;
				}
				else break;
			}
		}
};
posted @ 2018-07-17 21:26  Js2xxx  阅读(142)  评论(0编辑  收藏  举报