資料結構中的排序演算法是個非常重要的內容,經常出現在各種筆試考題當中。常見排序方法有:直接插入排序、希爾排序、直接選擇排序、堆排序、氣泡排序、快速排序等。分開進行講解——直接插入排序
void insertsort(int *arr,int n)
}
第一層迴圈->對陣列進行遍歷進行以下操作:對陣列的 第0-i的子串行進行從大到小的排序。i每增加1位,假設為d。便它目前的子串行進行遍歷,尋找它的位置,因為子串行之前已經是排好序了的,則若碰到比d大的數,則可以停止遍歷了,若沒有則將已遍歷的數字後移一位,相當於將d插入它應該在的位置。
其時間複雜度為o(n^2),空間複雜度為o(1)。相等的數字順序不會變化,所以該方法是--穩定排序
ps. 直接插入排序時間複雜度應與序列本身排序有關最小排序應為o(n),最大為o(n^2)```c
void shellsort(int *arr,int n)
arr[j+d]=x;
} }
}```
希爾排序的理論分析提出了許多困難的數學問題,特別是如何選擇增量序列才能產生最快的排序效果,至今沒有得到解決。希爾本身提出的步長設定為:di=n/(2)^i。
以下為排序舉例:
·原序列:時間複雜度處於o(nlbn)和o(n^2)之間a b c d e f g h i j
5 4 8 1 3 7 9 6 2 10
第一次步長:d1=10/2=5
即: a與f :插入排序
b與g :插入排序
c與h :
...e與j :插入排序
得到序列為:
5 4 6 1 3 7 9 8 2 10
第二次步長:d2=10/4=2
即: a-c-e-g-i:
b-d-f-h-j:
得到序列:
2 3 5 6 9
1 4 7 8 10
組合: 2 1 3 4 5 7 6 8 9 10
第三次步長:d3=10/8=1
即: a-b-c-d-e-f-g-h-i-j:
得到序列:
對整個序列插入排序-將d=1代入 與直接插入排序**一致:
即可得到:
1 2 3 4 5 6 7 8 9 10
void selectsort(int *arr,int n)
if(k!=i-1)
}}
直接選擇排序是一種簡單的排序方式,它每次從待排序的區間選出具有最小排序碼的數與該區間的第乙個元素進行交換。
例如:
待排序數列:在直接選擇排序中,共需要進行n-1次選擇和交換,每次選擇需要比較 n-i次,其中1<=i<=n-1a b c d e f g h
3 9 1 7 5 2 3 4
第一次:
k=0; arr[k]=3; 進入第二級迴圈
第二級迴圈為從b-h的數中 尋找比arr[k]小的數字,第一次找到c ,這是執行k=j即此時k=2
arr[k]=1,繼續尋找比1小的數字,沒有 ,此時k!=i-1 意味著arr[0]不是剩下序列的最小值,進行元素位置交換
即a[0]=1; arr[2]=3 a與c進行了交換
第二次:
k=1; arr[1]=9; 進入第二級迴圈
該迴圈為從c-h中的數字尋找,尋找後序數字中比9小,且最小的數字 進行交換
... 直到i=h k=g 判斷h 與g 哪個數字更大 結束迴圈 排序完成
直接選擇排序時間複雜度為o(n^2),但是由於它的移動記錄的總次數為o(n)數量級,所以當記錄占用的位元組數相對較多時通常比直接插入排序的執行速度要快一些
由於在直接選擇排序中存在著不相鄰元素之間的互換,因此可能會改變具有相同排序碼元素的前後位置,所以該方法是不穩定的
void sift(int *arr,int n,int i)
else break;
} arr[i]=x;
} void heapsort(int *arr,int n)
}
常用排序演算法
筆者最近學習演算法,學了很久也只弄懂了幾個排序演算法,在這裡曬一下下,作為以後參考之用。一 為什麼要研究排序問題 許多計算機科學家認為,排序演算法是演算法學習中最基本的問題,原因有以下幾點 l有時候應用程式本身需要對資訊進行排序,如為了準備客戶賬目,銀行需要對支票賬號進行排序 l很多演算法將排序作為...
常用排序演算法
一 簡單排序演算法 由於程式比較簡單,所以沒有加什麼注釋。所有的程式都給出了完整的執行 並在我的vc環境 下執行通過。因為沒有涉及mfc和windows的內容,所以在borland c 的平台上應該也不會有什麼 問題的。在 的後面給出了執行過程示意,希望對理解有幫助。1.冒泡法 這是最原始,也是眾所...
常用排序演算法
排序演算法 最好時間 平均時間 最壞時間 輔助空間 穩定性 直接插入排序 o n o n 2 o n 2 o 1 穩定 希爾排序 o n 1.3 o 1 不穩定 直接選擇排序 o n 2 o n 2 o n 2 o 1 不穩定 堆排序 o n x lbn o n x lbn o n x lbn o ...