#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;
}