堆排序
第一步:根据初始输入数据,利用堆的调整算法 siftDown()
形成初始堆
第二步:通过元素交换和重新调整堆进行排序。
建堆(大堆)
轻松教你建堆→
上面链接是建立小堆的,建立大堆在理解小堆之后,也是能轻松写出来的。
代码实现
//构造函数
maxHeap(T * arr, int sz)
{
heap = new T[sz];
heap = arr;
heapSize = sz;
_currentSize = sz;
/* for (int i = 0; i < sz; i++)
{
heap[i] = arr[i];
}*/
//从 (sz-2)/2 位置开始循环下滑
for (int j = (sz - 2) / 2; j >= 0; j--)
{
siftDown(j, sz);
}
}
//下滑算法,利用下滑算法轻松建堆
void siftDown(int currentPos, int currentSize)
{
int father = currentPos;
int child = father * 2 + 1;
T temp = heap[father];
while (child < currentSize)
{
if ((child + 1) < currentSize && heap[child] < heap[child + 1])
child = child + 1;
if (temp < heap[child])
{
heap[father] = heap[child];
father = child;
child = father * 2 + 1;
}
else
break;
}
heap[father] = temp;
}
排序
当我们已经建立大堆之后,堆顶的第一个元素 heap[0]
具有最大的排序码,将 heap[0]
与 heap[n - 1]
对调,把具有最大排序码的元素交换到最后,再对前面的 n - 1 个元素,使用堆的调整算法 siftDown(0 , n - 1)
,重新建立大堆。
代码实现
#include<iostream>
using namespace std;
template<class T>
class maxHeap
{
public:
//构造函数
maxHeap(int sz)
:heap(NULL)
, heapSize(sz)
{}
//构造函数
maxHeap(T * arr, int sz)
{
heap = new T[sz];
heap = arr;
heapSize = sz;
_currentSize = sz;
/* for (int i = 0; i < sz; i++)
{
heap[i] = arr[i];
}*/
//从 (sz-2)/2 位置开始循环下滑
for (int j = (sz - 2) / 2; j >= 0; j--)
{
siftDown(j, sz);
}
}
//堆排序
void heapSort()
{
currentPos = _currentSize - 1;
T currentSize = _currentSize;
while (currentPos > 0)
{
T temp = heap[0];
heap[0] = heap[currentPos];
heap[currentPos] = temp;
currentSize--;
for (int i = (currentSize - 2) / 2; i >= 0; i--)
{
siftDown(i, currentSize);
}
currentPos--;
}
}
void showHeap()
{
for (int i = 0; i < _currentSize; i++)
cout << heap[i] << " ";
}
private:
T * heap;//存放堆的数组
int heapSize;//堆的大小
int _currentSize;//堆的当前大小
int currentPos;//当前操作位置
//下滑函数构成最大堆
void siftDown(int currentPos, int currentSize)
{
int father = currentPos;
int child = father * 2 + 1;
T temp = heap[father];
while (child < currentSize)
{
if ((child + 1) < currentSize && heap[child] < heap[child + 1])
child = child + 1;
if (temp < heap[child])
{
heap[father] = heap[child];
father = child;
child = father * 2 + 1;
}
else
break;
}
heap[father] = temp;
}
};
int main()
{
int arr[6] = { 3, 2, 0, 9, 4, 5 };
maxHeap<int> s(arr, 6);
s.heapSort();
s.showHeap();
return 0;
}
时间复杂度
时间复杂度:O(1)
稳定性:不稳定排序算法