1. 程式人生 > 其它 >八大排序演算法~堆排序

八大排序演算法~堆排序

八大排序演算法~堆排序

1,思想:就是利用堆資料結構特點進行排序【堆結構特點~完全二叉樹,而咱排序主要是利用(大根堆或者小根堆特點進行排序)】

【小根堆】每一個父結點的值都比子結點小,因為每個父節點都比子結點小,咱知道 小根堆的最小值就在根結點

【大根堆】每一個父結點的值都比子結點大因為每個父節點都比子結點大,咱知道 根堆的最大值就在根結點

(補充一下,因為小根堆要求只是父結點大於子結點,沒有要求左右結點的大小關係噢,大根堆也是哈,咱對左右結點大小關係沒有關係哈)

2,接下來,咱以大根堆排序為例,講述好堆排序過程:

我覺得它的思想有些類似於咱總結的“冒泡思想”~

冒泡思想~(從小到大排序哈)【後座就認為是後邊哈,沒有啥特別,叫後座主要是為了強調後邊啦】

氣泡排序思想:從第一個數開始找,要把大數“排除在外”~為大數找後座。(從小到大排序哈)
  外層迴圈~需要放後的大數個數;
    內迴圈~從第一個數拿起與後面位置的數兩兩比較,實力強的佔的位置靠後。

堆排序思想~(從小到大排序哈)~剛好藉助大根堆的特點進行排序

堆排序(藉助大根堆,實現從小到大排序)思想:

咱對n個結點構建成一個大根堆,然後取根結點(最大值“排除在外”~放到後座上最後一個位置),

咱在對剩餘的n-1個結點構建成一個新的大根堆,然後又取根結點放到後座上倒數第二個位置,

然後對剩餘的n-2個結點構建成一個新的大根堆,然後又取根結點放到後座上倒數第三個位置,

........

直到剩下一個結點結束。

//過程:(1)建立成大根堆,

(2)for迴圈( i=最後一個結點位置開始直到i=第一個結點 結束):取根結點放於後座~即進行交換,根結點與後座最後一個位置進行交換,然後重構成新的大根堆,
再取根節點跟後座倒數第二個位置交換,然後重新構建新的大根堆,然後。。。


ps:本菜菜小白想請問,為什麼要先初始化堆,然後for迴圈 取根結點,重新調整成堆;
為什麼不能for迴圈 調整成堆,然後取根結點,然再次調整成堆,然後再取根結點,再調整成堆。。。。
就是為什麼要單獨初始化堆,不把它寫到迴圈裡?

3,程式碼:引自~《【演算法】排序演算法之堆排序》~https://zhuanlan.zhihu.com/p/124885051

【這個 “developer1024

” 作者大大這篇文章裡的動畫可以讓你秒懂堆排的】

#include <stdio.h>
#include <stdlib.h>
void swap(int* a, int* b) {
    int temp = *b;
    *b = *a;
    *a = temp;
}
void max_heapify(int arr[], int start, int end) {
    //建立父節點指標和子節點指標
    int dad = start;
    int son = dad * 2 + 1;
    while (son <= end) { //若子節點指標在範圍內才做比較
        if (son + 1 <= end && arr[son] < arr[son + 1]) //先比較兩個子節點大小,選擇最大的
            son++;
        if (arr[dad] > arr[son]) //如果父節點大於子節點代表調整完畢,直接跳出函式
            return;
        else { //否則交換父子內容再繼續子節點和孫節點比較
            swap(&arr[dad], &arr[son]);
            dad = son;
            son = dad * 2 + 1;
        }
    }
}
void heap_sort(int arr[], int len) {
    int i;
    //初始化,i從最後一個父節點開始調整
    for (i = len / 2 - 1; i >= 0; i--)
        max_heapify(arr, i, len - 1);
    //先將第一個元素和已排好元素前一位做交換,再從新調整,直到排序完畢
    for (i = len - 1; i > 0; i--) {
        swap(&arr[0], &arr[i]);
        max_heapify(arr, 0, i - 1);
    }
}
int main() {
    int arr[] = { 3, 5, 3, 0, 8, 6, 1, 5, 8, 6, 2, 4, 9, 4, 7, 0, 1, 8, 9, 7, 3, 1, 2, 5, 9, 7, 4, 0, 2, 6 };
    int len = (int) sizeof(arr) / sizeof(*arr);
    heap_sort(arr, len);
    int i;
    for (i = 0; i < len; i++)
        printf("%d ", arr[i]);
    printf("\n");
    return 0;
}