c語言n元陣列排序快速排序 兩種必須掌握的排序演算法

2021-10-17 08:25:59 字數 2531 閱讀 2360

文/edward

通常情況下,我們對陣列的操作遠遠不止遍歷判斷大小或者判斷奇偶數這麼簡單。比如,當我們需要求乙個陣列中所有元素的平均值時,操作很簡單,只需要去遍歷這個陣列,並將其內部所有元素中儲存的內容進行求和,最後用所有元素內容的和去除以元素個數,就可以得到最終陣列的平均值。這個問題很簡單。但是如果我們要求解這個陣列中的中位數時,應該怎麼做?此時我們來分析下,由於陣列中的數值存放順序並不是固定的,因此每個元素中儲存的內容並不一定是按照儲存數值從大到小存放的,也不一定是按照從小到大存放的。因此如果要求解中位數這樣的演算法,一定要對陣列中的內容進行排序,而陣列的排序操作是一種稍微有點難度的運算,因此這一小節的內容請大家開始全身貫注地看一下。

氣泡排序法

氣泡排序法冒泡演算法,在傳統的c語言教科書上講的很多,它是一種比較穩定的排序演算法。大家在使用這個排序演算法的時候,可以從它的名字來聯想一下它的實現形式。一說到冒泡,大家首先想到的是一條小魚在水裡游著,並且「布魯布魯」的吐出一串串小氣泡,冒到水面上。其實氣泡排序法也和小於吐泡泡一樣,每次只吐出乙個,並且連續不斷地乙個接乙個吐。氣泡排序演算法的中心思想,即是相鄰的兩個數進行比較後根據大小需求交換位置。先從最簡單的兩個元素的陣列看起,由此進行舉一反三。假設乙個陣列內部只有兩個元素「int array = ;」。對其進行排序時,我們僅需要做一次判斷即可以知道哪個元素大,哪個元素小,假設我們從小到大進行排列,那麼排列出的結果就應該是「array = ;」。再看當有三個元素的陣列。假設乙個陣列內部只有兩個元素「int array = ;」。那我們還是進行兩兩比較,第一次比較,可以得出陣列應該為「array = ;」,也是只需要一次比較就可以完成陣列的排序。但如果陣列改變一下元素的位置,即「int array = ;」,那麼我們再來看一下,第一次兩兩元素比較變成了「array = ;」,因此碰到這種極端情況時,冒泡法一次比較完成不了排序,那麼應該進行第二次比較,最終第二次比較我們可以得出結果「array = ;」再來看看四個元素時候陣列的排序,這次我們舉乙個極端情況,即將乙個從大到小排列的陣列變成由小到大的順序排列。陣列為「int array = ;」。那麼此時第一次相鄰兩個元素比較可以得出「array = ;」,第二次相鄰元素兩兩比較可以得出「array = ;」,第三次兩兩比較可以得出「array = ;」。基於上述的分析,我們可以知道,乙個陣列如果有n個元素需要進行排序時,其排序的極端情況應該是n-1次。具體的排序流程,如下。                           

氣泡排序法的流程

因此根據上述分析,我們可以寫出**如下。

冒泡法排序

接下來,我們將程式改裝一下,讓它在每一步相鄰兩個元素比較的過程列印出來,如圖5-4-3所示。我們可以看到,越大的元素會經由交換慢慢「浮」到數列的頂端(公升序或降序排列),就如同水裡的小金魚吐出的泡泡一串串慢慢浮出水面,故名「氣泡排序」。

冒泡法排序單步列印 

選擇排序法

選擇排序選擇排序,俗稱「硬著頭皮排序」,當然這個「硬著頭皮排序」是我給它取的名字,因為它是最最直觀的排序方法,完美詮釋了「暴力美學」這四個字。要理解選擇排序,先想象一下小學上體育課時,老師是怎麼排列隊伍的。先從小朋友裡面隨便拉乙個老師認為最矮的同學出來,讓他做排頭,然後依次拿其他的同學和他比較,如果比他高,就放到其後面去,比他矮就放到前面,接著再來目測第二個,以此類推。當然上面這段話是描述的體育老師內心思路。而我們對陣列排序的時候,同樣可以使用這種方式。我們可以先指定乙個排頭兵,假設我們要進行從小到大排列時,那我們先假設第乙個元素為陣列中最小的元素,接著分別去和剩餘的其它元素比較,如果發現比它小的,那麼將其自己和那個元素互換,用這種方式,只需要遍歷完整個陣列,就可以把最小的元素放到首個元素的位置了。如下所示。

選擇排序做一次遍歷比較

上圖中,我們通過第一次的遍歷比較,將最小的元素排列到了陣列的最左端,而接下來要做的,只需要一次將剩餘的9個元素進行比較,找出最小值,再放到0右邊,以此類推,最後我們可以寫出如下圖所示的選擇排序程式。

選擇排序法

對於陣列的排序演算法,我們目前就講述這兩種,其實還有很多現代的比較快速的排序演算法,我們以後再說。這兩種排序演算法對於很多第一次接觸c語言的讀者來說,還是比較難理解的,因此還是需要多花功夫多多演練。

兩種快速排序

快排是一種基於交換的排序,氣泡排序 兩兩相鄰作比較,逆序則交換 也是基於交換的排序,快排運用了二分法的思想,每次找乙個哨兵,比哨兵小的放一邊,大的放一邊,這是完成了一趟快排。冒泡 for int i 0 ia j 1 快排一 void quicksort int left,int right if ...

兩種分治排序 歸併排序和快速排序(C語言)

歸併排序 思想為 在對待排序列設定乙個中心點,以此為界左右進行拆分。在左子串行和右子串行遞迴執行上述過程,直到每個序列只有乙個元素,拆分不動為止。然後對相鄰元素進行合併。待合併完成為乙個大序列後,對相鄰的大序列遞迴執行這個過程,到整個序列的左 右序列合併完了,整個排序便完了。合併思想為 搞兩個指標分...

c語言的兩種排序方式(合併與快速)

合併排序 自定義型別 void swap type a,type b intpartition type a,int p,int r 把初始值換到中間,滿足演算法的思想 a p a j a j x return j void sort type a,int p,int r int main sort...