C++ 泛型 Heap 實現

鑑於自己沒寫過Heap,很是羞愧~於是今晚寫了一下~


1. 學習了下嵌套template的使用~ 實現部分就是

template <>

template<>

這種形式


2.使用函數對象傳遞函數,一開始忘了用實例化一個函數對象,語法老錯,真汗~


3. 想了下heap的push方法,只要在最後一個加上元素,然後從下往上“冒泡”就可以了~

可以證明是保持heap有效的


代碼:

heap.h

/*
Head:	Template Class Heap
Author:	Ding Yaguang / 2012-1-23
*/
#include <vector>
using namespace std;
#ifndef DINGYAGUANG_HEAP
#define DINGYAGUANG_HEAP

/*=============== heap類聲明 =====================*/
template<typename T,typename CMP = less<T>>
class heap
{
private:
	vector<T> _data;	//容器用的是vector,暫時不會適配器,所以定死了
	CMP _cmp;			//比較的 函數對象,默認是小於,即大頂堆
private:
	void _push_adjust(size_t n);
	void _adjust(size_t n);
	void _build();
	inline void _swap(T &a,T &b)
	{
		T t=a;
		a=b;
		b=t;
	}
public:
	heap();
	template<typename _RanIt> heap(_RanIt first,_RanIt end);
	template<typename _RanIt> void assign(_RanIt first,_RanIt end);
	size_t size();
	T pop();
	void push(T);
	T top();

};

//=========構造函數================
template<typename T,typename CMP>
heap<T,CMP>::heap():_data(T()),_cmp(CMP())
{

}


//嵌套模板,語法是瞎蒙的
template<typename T,typename CMP>
template<typename _RanIt>
heap<T,CMP>::heap(_RanIt first,_RanIt end):_data(first,end),_cmp(CMP())
{
	//填充第一位
	_data.insert(_data.begin(),T());
	_build();
}

//=============內部函數===================
template<typename T,typename CMP>
template<typename _RanIt>
void heap<T,CMP>::assign(_RanIt first,_RanIt end)
{
	//填充第一位
	_data.assign(first,end);
	_data.insert(_data.begin(),T());
	_build();
}

template<typename T,typename CMP>
void heap<T,CMP>::_push_adjust(size_t n)
{
	size_t parent = n>>1;
	if ( parent > 0)
	{
		if (_cmp(_data[parent],_data[n]))
		{
			_swap(_data[parent],_data[n]);
			_push_adjust(parent);
		}
	}
	
}

template<typename T,typename CMP>
void heap<T,CMP>::_adjust(size_t n)
{
	size_t L = n<<1;
	size_t R = L|1;

	if ( L <= size())
	{
		if (_cmp(_data[n], _data[L]))
		{
			_swap(_data[n],_data[L]);
			_adjust(L);
		}
	}
	if ( R <= size())
	{
		if (_cmp(_data[n], _data[R]))
		{
			_swap(_data[n],_data[R]);
			_adjust(R);
		}
	}
}

template<typename T,typename CMP>
void heap<T,CMP>::_build()
{
	size_t i;
	for ( i = size() / 2; i > 0; --i )
	{
		_adjust(i);
	}
}
//================接口=================
template<typename T,typename CMP>
T heap<T,CMP>::top()
{
	return _data[1];
}

template<typename T,typename CMP>
T heap<T,CMP>::pop()
{
	T ans = _data[1];
	_data[1] = *_data.rbegin();
	_data.pop_back();
	_adjust(1);
	return ans;
}

template<typename T,typename CMP>
void heap<T,CMP>::push(T val)
{
	_data.push_back(val);
	_push_adjust(size());
}

template<typename T,typename CMP>
size_t heap<T,CMP>::size()
{
	return _data.size()-1;
}


#endif


main.cpp

#include <stdio.h>
#include "heap.h"

int main()
{
	int A[]={6,2,3,5,4};
	int B[]={423,243,4231,75,332,797,423};

	heap<int> h0;
	heap<int> h(A,A+5);

	int i;
	for (i=0;i<5;++i)
	{
		printf("pop : %d\t",h.pop());
		printf("size:%d\n",h.size());
	}

	for (i=0;i<5;++i)
	{
		h.push(i);
		printf("top is %d\t",h.top());
		printf("size:%d\n",h.size());
	}

	for (i=0;i<5;++i)
	{
		printf("pop %d\n",h.pop());
	}

	h0.assign(B,B+5);
	for (i=0;i<5;++i)
	{
		printf("pop %d\n",h0.pop());
	}
	system("pause");
	return 0;
}



運行結果




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章