前言:在這裡總結一下各種排序方式以增強理解和之後複習方便,附帶一些優化方式
目錄
非線性時間
1.比較
1氣泡排序
2快速排序
2.插入
1插入排序
2希爾排序
3.選擇
1選擇排序
2堆排序
4.歸併
1二路歸併
2多路歸併
線性o(n)
1.計數排序
2.堆排序
3.基數排序
正文
1.簡單氣泡排序
兩層迴圈遍歷陣列:
內層迴圈進行交換:如果pre大於next ,swap(pre, next) => 實現最大元素交換到隊尾
外層迴圈進行遍歷:每次都把剩餘陣列中最大元素交換到隊尾,最後完成排序
最好最壞都是o(n^2)
平均時間複雜度o(n^2)
void bubblesort(int *a, int n) //3. 冒泡}}1.5優化氣泡排序}
優化一:標記是否交換過(陣列是否已經有序)
對於像1,2,3,5,4這種基本有序的數列,只用交換一次,後來的迴圈都是多餘的,所以可以加入falg標記是這一趟否交換過,沒有的話直接退出
void bubblesort(int *a, int n) //在優化一的基礎上,我們考慮這樣的情況:前面大部分無序,後面有序(如1,2,5,7,4,3,6,8,9,10),優化一併不起作用3. 冒泡
}if(!flag) //優化一:如果沒改動過(排好序了),直接返回
return
; }
}
優化二:記錄最後一次交換的位置,如果後面沒有交換,說明後面是有序的,跳過就好
3. 冒泡
}if(!flag)
return
; k=pos;//
優化二:跳到最後一次交換的位置
}}優化三:每次選擇最大的與隊尾交換,其實就是選擇排序,下面寫
2.快速排序
分治法(divide and conquer)、遞迴(recursion)的一種應用,總的思想:設定乙個基準p(pivot),把陣列分為兩部分:大於p,小於p。
對於每一部分再找p,再分,一直迴圈直到每個小佇列只剩乙個元素,排序完成
方法:下標left ,right:當前部分的邊界
下表 r, l:從兩邊往中間遍歷的兩個「指標」(後面被定在「出問題」(需要換位置)的我位置)
基準p=a[left] , l=left, r=right
從右邊開始,第乙個出問題的數賦給a[left](第乙個出問題的位置留乙個坑), l往右移動到第乙個出問題的數賦給剛才右邊的坑(l位置出現乙個坑)
一直迴圈,到最後坑的位置就是中間的位置,把p賦給坑,完成這次大迴圈
void quicksort(int *a,int left,int right) //2.5優化快速排序4.快速
else
//要把它放到左邊
}while(l//
從最左找比flag大的
else}}
a[l]=flag;
quicksort(a, left, l-1
); quicksort(a,r+1
,right);
}
快排的優化大部分就是對基準選擇的優化,在上面的**中,我們使用的是最左邊的元素a[left]作為p,這種選擇對於基本排好的情況(快排的最差情況)很慢,
基本山和最垃圾的氣泡排序差不多o(n^2),甚至更差,這肯定不行啊:
優化一:三數取中法
解決資料基本有序的(就是找到陣列中最小下標,最大下標,中間下標的數字,進行比較,把中間大的陣列放在最左邊)
取a[mid],a[left], a[right] 三者之中間大小的數作為基準p
int m=left+(right-left)/2;//優化二:隨機選擇法找到中間的數字的下標
if(arr[left]>arr[right])//
最左大於最右的時候,交換左右
if(arr[m]>arr[right])//
如果中間的》right ,交換
if(arr[m]>arr[left])//
如果中間的》left,交換
//這樣就把三個數中中間大小的數換到了left位置上,之後的程式和前面一樣
while
()
序列部分有序的時候,固定位置選取不好,隨機選
/*優化三:序列夠小是使用插入排序隨機選擇p的位置,區間在low和high之間
*/int selectpivotrandom(int arr,int low,int
high)
在數列比較短的時候,使用快排「大材小用」,5-20個資料以下的時候插入排序就比快排更快了,我們取10
#define max_len 10 //資料量小於10的時候用插入
void quick(int *arr,int left,int
right)
else
}
排序演算法小結 C 實現
include include 排序演算法的穩定性 對於相同的關鍵字,排序之前的位置和排序之後的位置相同,則稱為穩定排序,否則不穩定排序。歸併排序 基本思想為 先分解再合併,在合併的過程中進行排序 穩定排序 平均時間複雜度為 o nlogn 最好時間複雜度o nlogn 最好時間複雜度o nlogn...
C 排序演算法小結
1 計數排序 如果給定上下界,並且區間不大的話,最適用。比如對於英文本母陣列進行排序。時間複雜度o n 空間複雜度o n void countsort int a,int n,int low,int high int ind 0 for int i 0 i size i 2 氣泡排序 基礎版 最基礎...
C 排序演算法小結
前言 演算法這個東西其實在開發中很少用到,特別是web開發中,但是演算法也很重要,因為任何的程式,任何的軟體,都是由很多的演算法和資料結構組成的。但是這不意味著演算法對於每個軟體設計人員的實際工作都是很重要的。每個專案特點和需求特殊也導致演算法運用場景上不同。但是個人覺得演算法運用的好的話會給自己在...