heap的实现

4 篇文章 0 订阅
2 篇文章 0 订阅
#include <iostream>
#include <vector>
using namespace std;

void make_heap(vector<int>::iterator begin, vector<int>::iterator end);
void push_heap(vector<int>::iterator begin, vector<int>::iterator end);
void pop_heap(vector<int>::iterator begin, vector<int>::iterator end);
void sort_heap(vector<int>::iterator begin, vector<int>::iterator end);

int main()
{
	//vector<int> test{ 9, 5 ,4 ,1 ,1 ,3};
	//vector<int> test{ 5,1,4,1,1,3};
	//vector<int> test{ 10,8,5,7,5,1,3,4,2};
	//vector<int> test{ 7, 4 ,3, 1 ,2 };
	//vector<int> test{ 10,9,6,7,8,5,3 ,4 ,2 ,5 ,2 ,4 ,1 };
	vector<int> test{ 1,2,3,4,5,6,7,8,9,10,11};
	make_heap(test.begin(), test.end());
	for (auto i : test) {
		cout << i << " ";
	}
	return 0;
}


void make_heap(vector<int>::iterator begin, vector<int>::iterator end) {
	int a = *(begin + 2);
	int b = *(begin+1);
	int c =  *begin;
	int temp;
	if (a > b) temp = a, a = b, b = temp;
	if (b > c) temp = b, b = c, c = temp;
	if (a > b) temp = a, a = b, b = temp;
	int i = 4;
	while (begin+i<end)
	{
		push_heap(begin, begin + i);
		i++;
	}
	push_heap(begin, begin + i);
}

void push_heap(vector<int>::iterator begin, vector<int>::iterator end) {
	int len = end - begin;//求长度,知道插入元素的位置
	int parent = len / 2;//找父节点
	int child = len;
	while (parent>0)
	{
		//如果子节点的值比父节点的值要大就交换,否则就完成调整,退出循环
		if (*(begin + child-1) > *(begin + parent-1))
		{
			int temp = *(begin + parent-1);
			*(begin + parent-1) = *(begin + child - 1);
			*(begin + child-1) = temp;
		}
		else
		{
			break;
		}
		child = parent;//更新子节点
		parent = parent / 2;//更新父节点
	}
}

void pop_heap(vector<int>::iterator begin, vector<int>::iterator end) {
	int in_data = *(end - 1);
	int max = *begin;
	int parent = 1;
	while (true)
	{
		int r_child = 2 * parent+1;
		int l_child = 2 * parent;
		if (r_child > end - begin) break;//判断子节点是不是最后的节点
		if (l_child > end - begin) break;
		if (*(begin+r_child - 1) >= *(begin + l_child - 1)){
			*(begin+parent - 1) = *(begin+ r_child - 1);//更新父节点的值
			*(begin + r_child - 1) = in_data;//更新子节点的值
			parent = r_child;//更新父节点
		}
		else
		{
			*(begin+ parent - 1) = *(begin+ l_child - 1);
			*(begin + l_child - 1) = in_data;
			parent = l_child;
		}
	}
	/*------进行上溯(跟push_heap的算法差不多,起点是parent,改了几个数据而已)-------
	以0下标为起点,上面以1下标为起点
	*/
	int child = parent;
	parent = child / 2;
	while (parent > 0)
	{
		//如果子节点的值比父节点的值要大就交换,否则就完成调整,退出循环
		if (*(begin + child - 1) > *(begin + parent - 1))
		{
			int temp = *(begin + parent - 1);
			*(begin + parent - 1) = *(begin + child - 1);
			*(begin + child - 1) = temp;
		}
		else
		{
			break;
		}
		child = parent;//更新子节点
		parent = parent / 2;//更新父节点
	}
	*(end - 1) = max;
}

void sort_heap(vector<int>::iterator begin, vector<int>::iterator end) {
	while (end - begin>2)
	{
		pop_heap(begin, end);
		end--;
	}
	//只剩两个的时候交换一下位置就行了
	int temp = *(begin);
	*(begin) = *(begin + 1);
	*(begin + 1) = temp;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值