堆排序
C++實現的堆排序,分爲三個函數實現:
- 堆調整函數:保持最大/最小堆
- 堆構建函數:利用堆調整函數創建一個最大/最小堆
- 堆排序函數:每次取堆頂元素交換至數組最後,並將size減一,然後調整堆頂保持最大/最小堆
堆調整函數:
//調整堆爲數組a,需要調整的結點序號爲i,堆大小爲size
void HeapAdjust(int* a, int i, int size)
{
int left = 2 * i; //i結點的左孩子標號爲2*i
int right = 2 * i + 1; //i結點的右孩子標號爲2*i+1
int max = i; //保存這三個結點中值最大的標號
if (left <= size && a[left] > a[i])
max = left; //左孩子大於i結點
if (right <= size && a[right] > a[max])
max = right; //右孩子大於當前的max結點
if (max != i)
{
//當三個結點中最大的不是i時與i交換,保持最大堆
swap(a, max, i);
//交換後標號爲max的結點可能已經不是最大堆,需遞歸繼續調整max
HeapAdjust(a, max, size);
}
}
堆構建函數
void BuildHeap(int a[], int size)
{
//從樹的非葉子結點開始到樹頂端
for (int i = size / 2; i >= 1; i--)
{
HeapAdjust(a, i, size); //調整i號結點
}
}
堆排序函數
void HeapSort(int a[], int size)
{
BuildHeap(a, size); //首先構建一個堆
//循環到i=2,最後交換1號和2號結點
for (int i = size; i >= 2; i--)
{
swap(a, i, 1); //將堆頂元素與最後元素交換
size--;
HeapAdjust(a, 1, size); //調整堆頂元素
}
}
完整代碼:
#include <iostream>
using namespace std;
void swap(int a[], int i, int j)
{
int temp;
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
void HeapAdjust(int* a, int i, int size)
{
int left = 2 * i;
int right = 2 * i + 1;
int max = i;
if (left <= size && a[left] > a[i])
max = left;
if (right <= size && a[right] > a[max])
max = right;
if (max != i)
{
swap(a, max, i);
HeapAdjust(a, max, size);
}
}
void BuildHeap(int a[], int size)
{
for (int i = size / 2; i >= 1; i--)
{
HeapAdjust(a, i, size);
}
}
void HeapSort(int a[], int size)
{
BuildHeap(a, size);
for (int i = size; i >= 2; i--)
{
swap(a, i, 1);
size--;
HeapAdjust(a, 1, size);
}
}
void print(int a[], int size)
{
for (int i = 1; i < size; i++)
cout << a[i] << " ";
cout << a[size] << endl;
}
int main(int argc, char** argv)
{
int a[7] = { 0, 4, 6, 1, 5, 3, 2 };
cout << "排序之前的序列爲:" << endl;
print(a, 6);
HeapSort(a, 6);
cout << "排序之後的序列爲:" << endl;
print(a, 6);
return 0;
}