常用排序演算法及其實現

2021-10-09 13:32:01 字數 4539 閱讀 4107

1. 插入排序:遍歷陣列(n),將每個元素插入到前面子串行的合適位置(插入時採取前面的部分元素後移,再將本元素填在適當位置的方法)

模擬:12 30 9 100 1 3 10

12 30 9 100 1 3 10

9 12  30 100 1 3 10

9 12 30 100 1 3 10

1 9 12 30 100 3 10

1 3 9 12  30 100  10

1 3 9 10 12 30 100 

實現**:

1 /*

2 插入排序:

3 平均:o(n2)

4 最好:o(n)

5 最壞:o(n2)

6 穩定性:穩定

7 */

8 void insertsort(vector&nums)

9 25 }

26 }

27 }

2. 氣泡排序:雙層迴圈,外層從後往前,裡層從前往後,如果後面比前面小,就交換。

模擬:1 3 2 7 5 6 9 8 4

1 2 3 5 6 7 8 4 9

1 2 3 5 6 7 4 8 9

1 2 3 5 6 4 7 8 9

1 2 3 5 4 6 7 8 9

1 2 3 4 5 6 7 8 9

實現**:

1 /*

2 氣泡排序: 通過兩兩交換的方式,每次將子區間最大的冒向最後

3 平均:o(n2)

4 最好:o(n)

5 最壞:o(n2)

6 穩定性:穩定

7 */

8 //普通氣泡排序

9 void bubblesort(vector&nums)

10 24 }

25 }

26 }

27 28 //冒泡優化版本:新增標誌位或者計數器判斷序列是否已經有序

29 void bubblesort2(vector&nums)

30 45 else

46 flag ++;

47 }

48 if(flag == i)

49 return ;

50 }

51 }

3. (簡單)選擇排序:本位和後面子序列中最小的交換

模擬:1 3 2 7 5 6 9 8 4

1 3 2 7 5 6 9 8 4

1 2 3 7 5 6 9 8 4

1 2 3 7 5 6 9 8 4

1 2 3 4 5 6 9 8 7

1 2 3 4 5 6 9 8 7

1 2 3 4 5 6 9 8 7

1 2 3 4 5 6 7 8 9

實現**:

1 /*

2 選擇排序: 每個子區間找到最小與第乙個交換

3 平均:o(n2)

4 最好:o(n)

5 最壞:o(n2)

6 穩定性:穩定

7 */

8 void choosesort(vector&nums)

9 21 if (nums[i] > nums[min])

22 swap(nums[i], nums[min]);

23 }

24 }

4. 快排:思想是,一趟挑出1個數,將陣列分成左右兩部分,左邊小於該數,右邊大於該數。維護有兩個索引(low, high),隨機將陣列中乙個數定為「基準」,先從high右往左找到第乙個比基準小的與基準交換,更新low和high,再從low左往右找第乙個大於基準的與基準交換,更新low和high。直到low == high。進行下一趟,一般三趟足以。(第一堂完成後左邊再選乙個,右邊再選乙個即可。)

模擬:1 3 2 7 5 6 9 8 4

4 3 2 7 5 6 9 8 1

4 3 2 1 5 6 9 8 7

(一趟結束)

實現**:

1 /*

2 快速排序:

3 平均:o(nlogn)

4 最好:o(nlogn)

5 最壞:o(n2) 完全有序時出現

6 穩定性:不穩定

7 */

8 //分治法:遞迴實現

9 void quicksort(vector&nums, int l, int r)

10 24 //從右往左找到第乙個小於key的數

25 while(nums[--j] > key)

26

30 //判斷位置,交換兩數

31 if(i >= j)

32 break;

33 int tmp = nums[i];

34 nums[i] = nums[j];

35 nums[j] = tmp;

36 }

37 //分割完成後,遞迴兩部分

38 int tmp = nums[l];

39 nums[l] = nums[j];

40 nums[j] = tmp;

41 quicksort(nums, l, j-1);

42 quicksort(nums, j+1, r);

43 }

5. 堆排序:對所給陣列進行建大頂堆,將堆頂元素與最後乙個交換,尾索引前移,繼續建立大頂堆,如此類推。

1 /*

2 堆排序: 在陣列基礎上構建大/小頂堆來實現排序

3 平均:o(nlogn)

4 最好:o(nlogn)

5 最壞:o(nlogn)

6 穩定性:不穩定

7 */

8 //調整範圍堆頂值,保持大頂

9 void heapadjust(vector&nums, int index, int length)

10 25 return;

26 }

27 28 //堆排序:遞迴方式實現

29 void heapsort(vector&nums)

30 39 //堆排序

40 for (int i = len - 1; i >= 0; i--)

41

49 }

6.歸併排序:將原始陣列分成若干個子串行,兩兩合併排序,再合併排序......直到合併完成。

(同數量級排序方法中效能最好的---又快又穩定)

模擬:1 3 2 7 5 6 9 8 4

[1 3] [2 7] [5 6] [8 9] [4]

[1 2 3 7] [5 6 8 9] [4]

[1 2 3 5 6 8 9] [4]

[1 2 3 4 5 6 7 8 9]

實現**:

1 /*

2 二路歸併排序:

3 平均:o(nlogn)

4 最好:o(nlogn)

5 最壞:o(nlogn) 完全有序時出現

6 穩定性:穩定,但很少用

7 */

8 //合併二路陣列

9 void merge(vector&nums, vector&res, int l, int m, int r)

10 22 //剩下的部分

23 if(i <= m)

24

28 else

29

33 //將二路合併結果複製回去

34 for(int i=l; i<=r; i++)

35 nums[i] = res[i];

36 }

37 38 //二路分割

39 void mergesort(vector&nums, vector&res, int l, int r)

40 48 }

7. 希爾排序:要選步長,每隔乙個步長選定乙個元素,對選定的序列排序,再選一次再排;完成後換步長再排。步長的選取很重要,但沒有好的選取方法。

一位大佬的總結:

常用排序演算法及其實現

1.插入排序 遍歷陣列 n 將每個元素插入到前面子串行的合適位置 插入時採取前面的部分元素後移,再將本元素填在適當位置的方法 模擬 12 30 9 100 1 3 10 12 30 9 100 1 3 10 9 12 30 100 1 3 10 9 12 30 100 1 3 10 1 9 12 3...

kmeans演算法及其實現

k 均值演算法能夠使聚類域中所有樣品到聚類中心距離平方和最小。其原理為 先取 k個初始聚類中心,計算每個樣品到這 k個中心的距離,找出最小距離,把樣品歸入最近的聚類中心,修改中心點的值為本類所有樣品的均值,再計算各個樣品到新的聚類中心的距離,重新歸類,修改新的中心點,直到新的聚類中心和上一次聚類中心...

單鏈表的快速排序演算法及其實現

演算法思想 對於乙個鍊錶,以head節點的值作為key,然後遍歷之後的節點,可以得到乙個小於key的鍊錶和大於等於key的鍊錶 由此遞迴可以對兩個鍊錶分別進行快速。這裡用到了快速排序的思想即經過一趟排序能夠將小於key的元素放在一邊,將大於等於key的元素放在另一邊 面試回答 如果面試官問快速排序是...