码迷,mamicode.com
首页 > 编程语言 > 详细

c++ 堆的创建 堆排序

时间:2016-03-20 18:08:38      阅读:197      评论:0      收藏:0      [点我收藏+]

标签:c++;堆的基本操作;堆排序

#pragma once

#include<iostream>
#include<vector>
using namespace std;

class BigHeap//仿函数类  大堆返回true
{
public:
	bool operator()()
	{
		return true;
	}
};

class SmallHeap//仿函数类  小堆返回false
{
public:
	bool operator()()
	{
		return false;
	}
};
template <class T,class BigOrSmall>//BigOrSmall为实例化对象时传入模板类型 大堆或小堆
class Heap
{
public:
	vector<T> _array;
	BigOrSmall _isBigHeap;//通过实例对象 _isBigHeap 调用BigHeap或SmallHeap的operator()  得到不同Bool值来区分大堆小堆
public:
	Heap()
	{}

	Heap(int* a,size_t size)
	{
		for (size_t i = 0; i < size; ++i)
		{
			_array.push_back(a[i]);
		}
		{
			for (size_t i = (_array.size() - 2) / 2; i >= 0; --i)
			{
				AdjustDown(i);
				if (i == 0)
					break;
			}
		}
	}
	void Push(T data)
	{
		_array.push_back(data);
		AdjustUp(_array.size()-1);
	}

	void Pop()
	{
		swap(_array[0], _array[_array.size() - 1]);
		AdjustDown(0);
		_array.pop_back();
	}

	void HeapSort()//堆排序  O(n *Log* n)
	{
		size_t i = 0;//
		if (_isBigHeap())//判断大小堆
		{
			
			while (i < _array.size()-1)//i从0 循环
			{
				if (_array[i] < _array[i + 1])//每次左右交换
					swap(_array[i], _array[i + 1]);
				AdjustDown(i);//之后向下调整
				++i;
			}
			
		}
		else
		{
			while (i < _array.size() - 1)
			{
				if (_array[i] > _array[i + 1])
					swap(_array[i], _array[i + 1]);
				AdjustDown(i);
				++i;
			}
		}
		}

protected:
void AdjustDown(size_t index)//向下调整 初始化时用
{
	while (index < _array.size()-1)
	{
		if (!_isBigHeap())//调用仿函数
		{
			if ((index * 2 + 2)<=_array.size() - 1 && _array[index * 2 + 1]>_array[index * 2 + 2])
				swap(_array[index * 2 + 1], _array[index * 2 + 2]);
			if ((index * 2 + 1)<=_array.size() - 1 && _array[index] > _array[index * 2 + 1])
				swap(_array[index], _array[index * 2 + 1]);
		}
		else
		{
			if ((index * 2 + 2)<=_array.size() - 1 && _array[index * 2 + 1]<_array[index * 2 + 2])
				swap(_array[index * 2 + 1], _array[index * 2 + 2]);
			if ((index * 2 + 1)<=_array.size() - 1 && _array[index] <_array[index * 2 + 1])
				swap(_array[index], _array[index * 2 + 1]);
		}

		index = index * 2 + 1;
	}
}

//向上调整 每次push时用
void AdjustUp(size_t index)
{
	while (index!=0)
	{
		size_t i = (index-1)/2;
		if (!_isBigHeap())
		{
			if (index + 1 < _array.size() && _array[index] > _array[index + 1])
				swap(_array[index], _array[index + 1]);
			if (_array[i] > _array[index])
				swap(_array[i], _array[index]);
			else
				break;
		}
		else
		{
			if (index + 1 < _array.size() && _array[index] < _array[index + 1])
				swap(_array[index], _array[index + 1]);
			if (_array[i] < _array[index])
				swap(_array[i], _array[index]);
			else
				break;
		}
		index = i;
	}
}


};

#include"heap.hpp"//测试用例

using namespace std;

void test()
{
	int a[10] = { 10, 16, 18, 12, 11, 13, 15, 17, 14, 19 };
	Heap<int,SmallHeap> h1(a, 10);
	Heap<int, BigHeap> h2(a, 10);
	h1.Push(1);
	h1.Pop();
	h1.HeapSort();
}

int main()
{
	test();
	return 0;
}


c++ 堆的创建 堆排序

标签:c++;堆的基本操作;堆排序

原文地址:http://shaungqiran.blog.51cto.com/10532904/1753148

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!