c++ 堆的创建 堆排序

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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++ 如何在堆中创建一个类的对象? 谢谢!

c++堆排序

堆 与 堆排序

堆 与 堆排序

堆 与 堆排序