堆排序演算法(加詳細註釋版)
阿新 • • 發佈:2020-12-27
C語言堆排序程式碼
在這裡筆者只是對堆排序程式碼假如更加詳細的註釋,以便於學會原理但是看不懂或者不會自己編譯程式碼的初學者進行學習。本篇的程式碼來源來自大佬紫紅的紫紅的一篇文章:排序演算法之堆排序(Heap Sort)——C語言實現還不懂演算法的請先看一下這篇文章。
編譯環境是:VS2015
#include<stdio.h>
#include<stdlib.h>
//大頂堆,a[1]為最大值
void HeapAdjust(int a[], int s, int m)//a為儲存資料的陣列,s為正在調整的不正確的起點,m為陣列長度
{
int rc, j;//rc為a[s]的臨時儲存位置,j為迴圈變數,同時用來確定a[s]的兩個子樹在陣列中的位置,所以j=2s或者2s+1
rc = a[s];//儲存當前值
for (j = 2 * s; j <= m; j = j * 2)//先判斷左孩子,j=j*2意味著繼續修正下一個錯誤、
{//j<m因為陣列從1開始
if (j < m&&a[j] < a[j + 1]) j++;//j<m為前提條件,在左右孩子中選擇比較大的一個進行操作
if (rc > a[j]) break;//如果正在判斷的結點大於其左右子樹,則跳出迴圈,不進行操作
a[s] = a[j];//若需要調整,直接讓較大的子樹上位,到達原本結點
s = j;//此時判斷是否需要調整的結點變成剛上去的子樹,迴圈中該位置沒有賦予原本作為雙親的值,因為可能之後還需要調整,此處不一定是雙親正確的位置
}
a[s] = rc;//rc賦給了正確位置
}
void HeapSort(int a[], int n)//堆排序的主體程式
{
int temp, i, j;
for (i = n / 2; i > 0; i--)//從中間開始進行調整,最終初始化堆
{
HeapAdjust(a, i, n);
}
//排序
for (i = n; i > 0; i-- )//初始化i為最後一個數,為下面每次和最後一個值進行交換做鋪墊
{//i>0為終止條件是因為陣列從1開始
temp = a[1];
a[1] = a[i];
a[i] = temp;//交換第一個值和最後一個值
HeapAdjust(a, 1, i - 1);//交換完畢後再次進行調整,此時起點為第一個,儲存大小減一,最後一個被賦予了所有數的最大值
}
}
int main()
{
int n, i, *a;
printf("輸入陣列長度");
scanf("%d", &n);
a = (int*)malloc((n + 1) * sizeof(int));
printf("請輸入資料:");
for (i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
}
HeapSort(a, n);
printf("排序後:\n");
for (i = 1; i <= n; i++)
{
printf("%d<", a[i]);
}
system("pause");
}
執行效果: