常問的幾個基礎排序,要不再複習一下?

2021-10-06 18:33:11 字數 3303 閱讀 7874

github 位址

排序,不管是日常開發還是面試中,都會被光顧,雖然現在 jdk 的集合中提供了排序的方法,但是我們也得去熟悉一些基礎的排序演算法,這裡筆者給大家分享五個常問的基礎排序,冒泡、選擇、插入、希爾、快排。

氣泡排序,顧名思義就是排序元素時像冒泡一樣,把最大或者最小慢慢比較到陣列尾部,實現排序的方法。具體就是,如果有乙個長度為 n 的陣列 num,將 num[0] 與 num[1] 比較,如果 num[0] > num[1] ,則交換位置,反之則不交換。再比較 num[1] 和 num[2], 根據大小決定位置,一直交換到陣列結束。那麼 num[n-1] 一定是陣列中最大的。再次做上述比較,那麼 num[n-2] 一定是第二大的,一直迴圈直到整個陣列排序完成。 下圖只展示冒第乙個泡。

// -1 是因為我們比較 i 和 i+1,防止陣列越界

for(

int i =

0; i < num.length -

1; i++)}

}return num;

}選擇排序,就是第一次選擇陣列中最小的與第乙個交換,第二次選擇第二小的與第二個元素交換,直到交換到最後乙個。

}插入排序是從拿第二個元素開始,與左邊的元素挨個比較,找到比自己大的元素放,然後把自己放到該元素左邊,如果沒有就不換位置,再從第三個元素開始,直到排序完成。

}什麼是希爾排序呢?希爾排序是插入排序的改進版,我們可以看到,上面的插入排序在什麼時候排序會比較快呢?首先,和所有排序一樣,元素的個數少時,還有呢?我們可以看到,當陣列基本有序時,那麼插入排序就會更快。所以希爾排序是什麼改進的呢?希爾排序將陣列按照增量分割成若干個小組,利用插入排序完成排序,然後變小增量,再次分割並排序(這裡的分割只是邏輯上的分割,並沒有真正將陣列分成幾個新的陣列)。下面來詳細說一下:

先解釋一下,增量為每組陣列兩個元素之間下標差值,一般來說第一次增量為陣列長度的一半,第二次分組的增量為上次的增量的一半,一直到增量為 1。可以看到,第一次分組插入排序後,每組有序,陣列大致有序,我們再接著分組:

如果再次分組的話,grow = grow/2 = 1,這樣的增量為1,就不需要分組了,我們可以看到現在的陣列比原陣列有序多了,使用現在的陣列比進行插入排序會比原陣列快很多。

**表示(其實就是分組使用插入排序):

public

int[

]order

(int

num)

for(

int grow = num.length/

2; grow >

0; grow/=2)

else

k++;}

}}return num;

}

快速排序就是我們經常聽到的快排,那麼快排是怎麼對陣列進行排序的呢?快排中有比較重要的三個變數,基準、左指標,右指標。基準一般是陣列的第乙個元素,左指標指第乙個元素,右指標指最後乙個元素,分別從左右指標指的元素與基準比較,比基準大的放右邊,比基準小的放左邊。這樣到最後,就會找到乙個數,這個數的左邊都比這個數小,右邊都比這個數大,然後再遞迴按照上面的方法分別遍歷這個數的左區間和右區間,一直遍歷到左右區間只有乙個數時,則排序完成。具體見下圖:

接著遞迴左區間和右區間,左區間的基準元素為 1,左指標元素為 1,右指標元素為 4,右區間的基準元素為 7,左指標元素為 7,右指標元素為 8,一直遞迴到所有的子左區間和子右區間元素個數為 1,則排序完成。具體**如下:

public

int[

]order

(int

num)

sort

(num,

0,num.length-1)

;return num;

}public

void

sort

(int

num,

int l,

int r)

// 因為 l,r 還需要給左右區間確定範圍,所以使用臨時變數移動指標

int index = l,left = l,right=r;

while

(left < right)

// 再比較左邊

while

(num[index]

>=num[left]

&& left

if(left

}// 交換基準元素

int temp = num[index]

; num[index]

= num[left]

; num[left]

= temp;

index = left;

// 遞迴左區間

sort

(num,l,index-1)

;// 遞迴右區間

sort

(num,index+

1,r)

;}

面試常問 堆排序

思路 分析 改進 思路 堆排序有兩種,一種利用堆的特性,先構建最大堆,每次得到最大堆的堆頂元素 另一種是直接原地使用堆排序。原地堆排序 將陣列構建成堆,交換陣列的第乙個元素和最後乙個元素。依次對除去最後的元素的剩下陣列進行排序。原地排序 public class main heapsort arr,...

初學者常問的幾個問題

隔行如隔山,初學程式設計往往不知道從何入手,非常迷茫,以下幾個問題是我經常被問到的,總結出來分享給讀者。這是乙個沒有答案的問題。每個人投入的時間 學習效率和基礎都不一樣。如果你每天都拿出大把的時間來學習,那麼兩三個月就可以學會c c 不到半年時間就可以編寫出一些軟體。但是有一點可以肯定,幾個月從小白...

python基礎之面試常問

參考 python面試常問 目錄python記憶體管理 原博文 python記憶體管理 python垃圾 lambda作為乙個表示式,定義了乙個匿名函式。lambda表示式是起到乙個函式速寫的作用,允許在 內嵌入乙個函式的定義。例如 func1 lambda x,y x y def func2 x,...