【数据结构】实现大小堆也叫二叉堆(类似c++中的优先队列)

二叉堆:

是一种特殊的堆,依赖于完成完全二叉树和向量实现的。分为最大堆和最小堆。



最大堆:父节点的键值总是大于或等于任何一个子节点的键值。

【数据结构】实现大小堆也叫二叉堆(类似c++中的优先队列)_第1张图片

最小堆:父节点的键值总是小于或等于任何一个子节点的键值。

【数据结构】实现大小堆也叫二叉堆(类似c++中的优先队列)_第2张图片


存储:二叉树一般用数组来存储表示,在下面的实现中使用了STL中的vector。根节点在数组中的位置是0,第n个位置的左孩子下标为n*2+1,右孩子为2*n+2 ,当前孩子存在的前提是计算后下标要小于数组总个数。而用孩子结点的下标c,可以计算出双亲的下标(c-1)/2。


基本操作:可以进行插入结点,移除最小的结点,和返回最小的结点,返回当前堆中元素个数。


代码:这个是用模板参数实现,传入函数对象生成大小堆,默认小堆:

#ifndef _HEAP_H_
#define  _HEAP_H_
#include 
#include 
#include 
using namespace std;

// 仿函数小堆调用 
template 
class Less
{
public:
	bool operator()(const T& left, const T& right)
	{
		return left <= right;
	}
};
// 仿函数大堆调用
template 
class Greater
{
public:
	bool operator()(const T& left, const T& right)
	{
		return left > right;
	}
};

	 
		

// 模板参数的大小堆

template >
class Heap
{
public:
	Heap(){}
	Heap(const T arr[] , int size)
	{
		for (int i=0; i=0; --last)
		{
			_AdjustDown(last, size);
		}
	}
	void Insert(const T data)
	{
		_heap.push_back(data);
		_AdjustUp(_heap.size());
	}

	T& Top()
	{
		assert(!_heap.empty());

		return _heap[0]; 
	}
	const T& Top()const
	{
		assert(!_heap.empty());

		return _heap[0]; 
	}
	void Remove()
	{
		int size = _heap.size();
		if (size > 1)
		{
			std::swap(_heap[0], _heap[size-1]);
			_heap.pop_back();
			_AdjustDown(0, _heap.size());
		}
		else
		{
			_heap.pop_back();
		}
	}
private:
	void _AdjustUp(int size)
	{
		int child = size - 1;
		int parent = (child-1)/2;
		while (child != 0)
		{
			// 孩子小于父亲
			if (Compare()(_heap[child], _heap[parent]))
			{
				std::swap(_heap[child], _heap[parent]);
				child = parent;
				parent = (child - 1 )/2;
			}
			else
			{
				break;
			}
		}
	}
	void _AdjustDown(int root, int size)
	{
		int child = root*2 + 1;
		int parent = root;

		while (child < size)
		{
			if (child+1 < size && Compare()(_heap[child+1], _heap[child]) )
			{
				child += 1;
			}
			// 小 less 
			if (Compare()(_heap[child], _heap[parent]))
			{
				std::swap(_heap[child], _heap[parent]);
				parent = child;
				child = child *2 + 1;
			}
			else
			{
				break;
			}
		}
	}
private:
	vector _heap;
};
#endif _HEAP_H_

这个是用模板的模板参数实现:

#ifndef _HEAP_H_
#define  _HEAP_H_
#include 
#include 
#include 
using namespace std;

// 仿函数小堆调用 
template 
class Less
{
public:
	bool operator()(const T& left, const T& right)
	{
		return left <= right;
	}
};
// 仿函数大堆调用
template 
class Greater
{
public:
	bool operator()(const T& left, const T& right)
	{
		return left > right;
	}
};


// 模板的模板参数 大小堆
template class Compare = Less>
class Heap
{
public:
	Heap(){}
	Heap(const T arr[], int size)
	{
		for (int i=0; i=0; --i)
		{
			_AdjustDown(i, size);
		}
	}

	void Insert(const T& data)
	{
		_heap.push_back(data);
		_AdjustUp(_heap.size());
	}

	void Remove()
	{
		if (!_heap.empty())
		{
			if (_heap.size()>1)
			{
				std::swap(_heap[0], _heap[_heap.size()-1]);
				_heap.pop_back();
				_AdjustDown(0, _heap.size());
			}
			else
			{
				_heap.pop_back();
			}
		}
	}
	T& Top()
	{
	assert(!_heap.empty());

	return _heap[0]; 
	}
	const T& Top()const
	{
	assert(!_heap.empty());

	return _heap[0]; 
	}
private:
	void _AdjustUp(int size)
	{
		int child = size-1;
		int  parent= (child-1)/2;
		while (child != 0)
		{
			if (Compare()(_heap[child], _heap[parent]))
			{
				std::swap(_heap[child], _heap[parent]);
				child = parent;
				parent = (child-1)/2;
			}
			else
			{
				break;
			}
		}
	}
    void _AdjustDown(int root, int size)
	{
		int parent = root;
		int child = root*2 + 1;

		while (child < size)
		{
			if (child+1 < size && Compare()(_heap[child+1],_heap[child]) )
			{
				child  = child+1;
			}
			if (Compare()(_heap[child], _heap[parent]))
			{
				std::swap(_heap[child], _heap[parent]);
				parent = child;
				child = child*2 + 1;
			}
			else
			{
				break;
			}
		}
	}

	private:
	vector _heap;
};
#endif _HEAP_H_



你可能感兴趣的:(C/C++,C/C++/数据结构)