https://www.cnblogs.com/jingmoxukong/p/4303826.html 首先应该先了解堆的基础知识。 再向下调整或者向上调整时,要明确的几个点。 设当前元素在数组中以R[i]表示,那么, (1) 它的左孩子结点是:R[2i+1]; (2) 它的右孩子结点是:R[2i+2]; (3) 它的父结点是:R[(i-1)/2]; 本质是对一颗完全二叉树的操作。
#pragma once
#include <iostream>
#include <vector>
using namespace std;
class BigHeap
{
public:
bool operator()()
{
return true;
}
};
class SmallHeap
{
public:
bool operator()()
{
return true;
}
};
template<class T, class BigOrSmall>
class Heap
{
public:
std::vector<T> array_;
BigOrSmall big_heap_;
Heap(int* arr, size_t size)
{
for (int i = 0; i < size; i++)
{
array_.push_back(arr[i]);
}
for (int i = (array_.size() - 2) / 2; i >= 0; i--)
{
AdjustDown(i);
}
cout << endl;
for (int i = 0; i < size; i++)
{
cout << array_[i] << " ";
}
}
void Push(T data)
{
array_.push_back(T);
AdjustUp(array_.size() - 1);
}
T Pop()
{
swap(array_[0], array_[array_.size() - 1]);
T tmp = array_[array_.size() - 1];
array_.pop_back();
AdjustDown(0);
cout << endl;
return tmp;
}
void HeapSort()
{
int i = 0;
if (big_heap_())
{
while (i < array_.size() - 1)
{
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 (big_heap_())
{
if ((index * 2 + 2) < array_.size() && array_[index * 2 + 1] < array_[index * 2 + 2])
{
swap(array_[index * 2 + 2], array_[index * 2 + 1]);
}
if ((index * 2 + 1) < array_.size() && array_[index * 2 + 1] > array_[index])
{
swap(array_[index], array_[index * 2 + 1]);
}
}
else
{
if ((index * 2 + 2) < array_.size() - 2 && array_[index * 2 + 1] > array_[index * 2 + 2])
{
swap(array_[index * 2 + 2], array_[index * 2 + 1]);
}
if ((index * 2 + 1) < array_.size() - 2 && array_[index * 2 + 1] < array_[index])
{
swap(array_[index], array_[index * 2 + 1]);
}
}
index = index * 2 + 1;
}
}
void AdjustUp(size_t index)
{
while (index != 0)
{
size_t i = (index - 1) / 2;
if (big_heap_())
{
if (index + 1 < array_.size() && array_[index + 1] > array_[index])
swap(array_[index + 1], array_[index]);
if (array_[i] < array_[index])
swap(array_[index], array_[i]);
else
break;
}
else
{
if (index + 1 < array_.size() && array_[index + 1] < array_[index])
swap(array_[index + 1], array_[index]);
if (array_[i] > array_[index])
swap(array_[index], array_[i]);
else
break;
}
index = i;
}
}
private:
Heap() {}
};
|