九大排序,Java實現

九大排序,Java實現(附代碼)

今天整理了一下九大排序,分享一波,以下例子都測試過,都進行升序排序
在這裏插入圖片描述
先從簡單選擇排序講起:
簡單選擇排序,穩定
從待排序序列中選取一個最小的數,與當前序列最左邊的數交換
如:
第一趟:在n個元素中選出最小的一個元素與數組0號索引上的元素交換,
第二趟:在剩下的 n - 1 個數中找到最小的數, 與第數組1號索引上的元素交換,
以此類推,n個元素需要選擇 n - 1趟,序列全部有序

代碼實現:

在這裏插入圖片描述
上述簡單選擇排序,每次遍歷只維護一個最小值,與待排序序列的第一個位置交換,

優化:

2元選擇排序, 每次遍歷保存待排序數的最大值,和最小值
最小值與待排序序列最左邊的元素交換, 最大值與最右邊的元素交換
在這裏插入圖片描述
堆排序
堆排序,不穩定
選擇排序的一種,就是每次選擇一個最大(或最小)的值,
存放到正確的位置。
那麼該如和選擇呢:
堆排序核心思想:將待排序序列建成堆,得到最大(最小)值,存放到正確位置
首先知道使用數組存儲一顆完全2叉樹, 從0開始計數,
大頂堆:所有父節點元素的值 >= 兩個子節點的值
那麼 i 節點的左子節點爲 2 * i + 1, 右子節點爲 2 * i + 2;
我們把待排序序列建成一個大頂堆
從最後一個葉子節點的父節點((size - 1)/ 2)開始往前遍歷,建立大頂堆,即,比較兩個子節點的值,與父親節點的值,如果子節點值大於父節點,則交換
第一趟找到 [0, data.length - 1]序列中最大的數存放到 data.length - 1
第一趟找到 [0, data.length - 2]序列中最大的數存放到 data.length - 2,
每次取得最大值,都需要從下往上交換 , 以此類推得到有序序列

代碼

在這裏插入圖片描述
在這裏插入圖片描述
冒泡排序, 穩定:
交換排序的一種,比較相鄰的元素,如果左邊的元素大於右邊的元素,就交換他們兩個。
每一趟交換,都在待排序數中找到最大的元素,
存放在最待排序數中的最右邊
10個元素第一趟時需比較9次,將最大的元素移動到最後一位
第2趟時,待排序數變爲9個,需比較8次, 找到第2大的數,存放在倒數第2爲,以此類推

代碼

在這裏插入圖片描述
快速排序, 不穩定:
使用遞歸分治思想, 交換排序的一種
選擇一個基準數,通常選擇第一個元素或者最後一個元素
經過一趟排序後,左邊一部分比基準數小,右邊一部分比基準數大
將基準數存放至交界位置
然後分別對這兩部分進行同樣的排序,直到每部分元素個數爲1,則此時整個序列有序
在這裏插入圖片描述
簡單插入排序,穩定
初始時,第0號元素默認有序, 從第1號元素開始,往前搜索,找到正確的位置
在這裏插入圖片描述
希爾排序,縮小增量排序, 不穩定
每趟排序根據增量scan, 將待排序序列分爲scan組,在組內進行直接插入排序。一趟後,每個組內有序,再縮小增量繼續分組排序,直至增量爲1,整個序列有序

代碼:

在這裏插入圖片描述
在這裏插入圖片描述
歸併排序,穩定
過程分爲:先拆分,再歸併
拆分:即每次將待排序序列分爲兩部分
歸併: 當每部分拆分至只有一個元素時,此時每部分都有序,兩兩開始歸併,
歸併兩個有序序列的時間複雜度爲 O(n)

代碼:

在這裏插入圖片描述
在這裏插入圖片描述

那麼最後還有兩個接近線性的排序算法,雖然並不是,hhhh
桶排序, 穩定
桶排序, 穩定
需要k(當前數組的最大值)個輔助空間, 將當前數組中的元素與計數數組的下標對應
即將對應下標的值加一, count[data[i]]++;
若要得到得到升序序列,從左向右遍歷, 若要得到降序序列從右往左遍歷即可優化:可將計數數組的長度設爲 max - min + 1, 那麼需要多維護一個原數組的最小值
要保證穩定性,需對計數數組,從後往前遍歷
若需要降低空間複雜度可以將一組數,放入一個桶中,
再對桶中的元素(桶中可使用其他排序方法)
在當待排序數組內有大量重複的數值並且這些數值較爲集中時,使用桶排序效率較好,基本達到O(n)

代碼:

在這裏插入圖片描述
基數排序
基數排序, 桶排序的延伸
對數字的每位進行桶排序

代碼:

在這裏插入圖片描述
對exp位進行桶排序(1代表個位, 10代表十位,以此類推)
在這裏插入圖片描述