heap 排序

#include <iostream>
#include <vector>

using namespace std;

/* heap sort
 * head 是一个完全二叉树,heap sort的算法是in-place算法,运行边界在 O(nlogn)
 */

namespace My_heap
{
	class heap
	{
	public:
		heap(const vector<int> &d):data(d), size(d.size()){data.insert(data.begin(), 0);}
		void build_max_heap();
		int max_val(){return data[1];};
		vector<int> heap_sort();

	private:
		vector<int> data;
		int size;
		void build_max(int head);
	};
	
	void heap::build_max_heap()
	{
		// 自底而上建立大根堆
		// 1-[n/2] 是非叶节点,只需要对这些节点调整即可
		for (int i = size >> 1; i >= 1; -- i)
		{
			build_max(i);
		}
	}// end build_max_heap

	vector<int> heap::heap_sort()
	{
		// 每次插入最大值,然后交换第一个和最后元素,再重建heap
		vector<int> re;
		for(int i = size; i >= 1; -- i)
		{
			build_max_heap();
			re.push_back(max_val());
			int temp = data[1];
			data[1] = data[size];
			data[size] = temp;
			-- size;
		}
		return re;
	}

	void heap::build_max(int head)
	{
		// 调整head为root的heap
		// 为了方便计算left和child的index,index从1开始计数
		// left = head * 2, right = head * 2 + 1
		int left = head << 1;
		int right = left + 1;

		if (left <= size)
		{
			if (right <= size)
			{
				int max_index = (data[left] > data[right] ? left : right);
				max_index = (data[head] > data[max_index] ? head : max_index);
				if (max_index != head) // swap and build
				{
					int temp = data[max_index];
					data[max_index] = data[head];
					data[head] = temp;
					if (max_index == left)
						build_max(left);
					else
						build_max(right);
				}
			}
			else
			{
				if (data[head] < data[left])
				{
					int temp = data[left];
					data[left] = data[head];
					data[head] = temp;
				}
			}
		}
	}// end build_max

};

void show(const vector<int> &v)
{
	for(vector<int>::const_iterator it = v.begin(); it != v.end(); ++ it)
		cout << *it << " ";
	cout << endl;
}

int main()
{

	int b[10] = {3, 4 ,5, 1, 2, 9, 8, 10, 20, 11};
	vector<int> a(b, b + 10);
	show(a);

	My_heap::heap h(a);
	vector<int> sa(h.heap_sort());
	show(sa);

	return 0;
}
	

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值