堆排序
第一步:根據初始輸入數據,利用堆的調整算法 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)
穩定性:不穩定排序算法