#include<iostream>
#include<vector>
using namespace std;
template<class T>
class Less //仿函数
{
public:
Less()
{}
bool operator()(const T& l, const T& r)
{
return l < r; //实现小堆
}
};
template<class T>
class Greater
{
public:
Greater()
{}
bool operator()(const T& l, const T& r)
{
return l > r; //实现大堆
}
};
template <class T, class compare = Less>
class Heap
{
public:
Heap(T* array = NULL, size_t size = 0)
{
for (int i = 0; i < size; i++)
{
_arr.push_back(array[i]); //将数据存入顺序表中
}
int root = size / 2 - 1;
for (; root >= 0; root--)
{
_AdjustDown(root, _arr.size());
}
}
void push(const T& x) //插入一个叶子节点
{
_arr.push_back(x);
_AdjustUp();
}
void pop() //删除堆的根节点
{
_arr[0] = _arr[_arr.size() - 1]; //将最后一个节点的值赋给第一个节点,相当于删除第一个节点
_arr.pop_back(); //删除最后一个节点
int root = _arr.size() / 2 - 1; //重新排序
for (; root >= 0; root--)
{
_AdjustDown(root, _arr.size());
}
}
T& Top()
{
return _arr.front();
}
bool Empty()
{
return _arr.empty();
}
void HeapSort() //堆排序
{
for (int i = _arr.size(); i >= 1; i--)
{
swap(_arr[0], _arr[i - 1]);
int root = (i - 1) / 2 - 1;
for (; root >= 0; root--)
{
_AdjustDown(root,i - 1);
}
}
}
void Print()
{
for (int i = 0; i < _arr.size(); i++)
{
cout << _arr[i] << " ";
}
cout << endl;
}
private:
void _AdjustDown(int root, int size)
{
int left = root * 2 + 1;
int right = left + 1;
int key = left;
while (left < size)
{
if (right < size) //防止越界
{
if (compare()(_arr[right], _arr[left]))
{
key = right;
}
}
if (compare()(_arr[key], _arr[root]))
{
swap(_arr[key], _arr[root]);
//所有变量都要更新
root = key;
left = root * 2 + 1;
right = left + 1;
key = left; //重要
}
else
{
break;
}
}
}
void _AdjustUp()
{
int root = (_v.size() - 2) / 2;
int child = _v.size() - 1;
//while ((root >= 0) && (_v[root] < _v[child]))
// 当child==0时,则上调完成。不能使用parent来判断,parent不会小于0
while ((child > 0) && Com()(_v[child],_v[root]))
{
swap(_v[root], _v[child]);
child = root;
root = (child - 1) / 2;
}
private:
vector<T> _arr;
};
template<class T>
class PriorityQueue //优先级队列
{
public:
PriorityQueue()
{}
void push(const T& x)
{
hp.push(x);
}
void pop()
{
hp.pop();
}
T& top()
{
return hp.Top();
}
bool empty()
{
return hp.Empty();
}
private:
Heap<T, Less<T>> hp;
};
//在30个无序的数中找到最大的前十个
void TestFindMax()
{
int arr[30] = { 10, 16, 18, 12, 11, 13, 15, 17, 14, 19 ,99,32,45,67,89,34,98,77,56
,54,12,78,6,5,2,90,65,23,100,97};
Heap<int, Less<int>> hp(arr, 10);
int size = sizeof(arr) / sizeof(arr[0]);
for (int i = 10; i < size; i++)
{
hp.pop(); //删掉最小的
hp.push(arr[i]);
}
hp.Print();
}
void TestHeap()
{
int arr[10] = { 10, 16, 18, 12, 11, 13, 15, 17, 14, 19 };
Heap<int,Greater<int>> hp(arr, 10);
hp.push(20);
hp.pop();
hp.HeapSort();
hp.Print();
}
void TestPriorityQueue()
{
PriorityQueue<int> pq;
pq.push(4);
pq.push(6);
pq.push(2);
pq.push(8);
cout << pq.top() <<" ";
pq.pop();
cout << pq.top() << " ";
pq.pop();
cout << pq.top() << " ";
pq.pop();
cout << pq.top() << " ";
}
int main()
{
TestHeap();
//TestPriorityQueue();
//TestFindMax();
getchar();
return 0;
}
堆的实现及堆的各种应用
最新推荐文章于 2023-05-09 00:32:58 发布