個人對堆排序的理解
- 第一步:是建立length堆,根節點要比子結點大。
- 第二步:把最父結點與最後一個葉子節點交換。這樣堆被破壞。
- 第三步:建立 length-1 的堆。跳轉到第一步,一直迴圈到,length=0 停止。
- 堆排序快就快在,在建立的堆裡找最大值相當於折半查詢的速度非常樂觀。不用不全部掃一遍。
######時間複雜度
- 平均速度 o(n*logn)
- 不穩定排序
C版本 #include <stdio.h>
/*
s: 待比較 的節點
分三步走
1.比較s節點下左右子節點的哪一個大
2.其中大的一個節點 與 s節點 比較大小。
3.如果 子節點沒有s大 則結束, 比s節點大就交換他們的數值,然後繼續向子節點
*/
void HeapAdjust(int H[],int s, int length)
{
int temp = H[s];
int child = 2 * s + 1; //這裡child是左孩子的位置,child+1代表右孩子
while (child < length) { //防止 越界。
if (child+1 < length && H[child]<H[child+1]){//防止越界 且,找到左右孩子哪一個比較大。
child++;//右孩子大
}
if (H[child] > H[s]){//比父節點的數值大
H[s] = H[child];//複製給 s 節點
s = child; //調整 s,下一個節點
child = 2 * s + 1;
H[s] = temp;// 交換
}else{
break; //子節點沒有比父節點大
}
}
}
///初始化 堆
void BuildingHeap(int H[], int length)
{
///i 等於 最後一個有孩子的結點位置, 一直從堆底走到堆頂。
for(int i = (length - 1) / 2; i >= 0; i--)
HeapAdjust(H,i,length);
}
///堆排序
void HeapSprt(int H[],int length)
{
BuildingHeap(H, length);//建立初始化堆
///這裡是 從堆裡選擇最大的跟節點與跟最後節點交換,後堆排序
//然後堆次大的與倒數第二的節點交換,後堆排序
// 節點與根節點重合結束,從小到大排序結束
for (int i = length - 1; i > 0; i--)
{
int temp = H[0]; H[0] = H[i]; H[i] = temp; ///把 棧頂交換了。
HeapAdjust(H, 0, i);
}
}
int main(){
int a[10] = {8,9,7,0,3,4,5,2,1,6};
HeapSprt(a, 10);
for (int j = 0; j<10; j++) {
printf("%d ",a[j]);
}
printf("\n");
}
複製程式碼
- ######看我那麼可愛n(≧▽≦)n
- 關注我的微薄 (樑同桌):http://weibo.com/tongrenyinsheng
- 個人部落格: http://www.liangtongzhuo.com
- ios 個人寫的app (同人音聲)ASMR音樂