二、選擇排序:
選擇排序十分的簡單和直觀,其的工作原理是每一次從待排序的陣列中選出最小(或最大)的乙個元素,存放在序列的起始位置。因此,選擇排序也是像我們這種萌新最容易寫出來的排序演算法。
排序步驟:
選出最小的元素
放在陣列最前面
選出第二小的元素
放在第二位
重複如此直到完成排序
下面舉個栗子:
有乙個陣列其元素如下 5 1 4 3 2 6 7 0 9,其選擇排序流程如下
從這個栗子,我們可以得出選擇排序的核心**:
if (arr[min] > arr [j])
arr[min] = arr[min] ^ arr[i];
arr[i] = arr[min] ^ arr[i];
arr[min] = arr[min] ^ arr[i];
接著我們繼續思考,兩層for迴圈,首先是第一層,第一層迴圈有兩個作用,第乙個:從0~n-1乙個個進行排序;二:表示需要比較的次數。由第乙個作用我們可以知道第一層for迴圈的迴圈變數i<=n-1,由第二個作用可知i然後我們來確定一下第二層for迴圈,第二層for迴圈的作用很簡單就是讓當前元素與無序的元素進行比較,這裡的難點在於無序的元素和當前元素的確定,讓我們來回憶一下,第一層for迴圈的i是從0開始的那麼我們的第二層for迴圈為了避免重複比較,所以第二層for迴圈的迴圈變數j應該從i+1開始,到**裡終止呢?因為每一次都是把最下的元素放到最前面所以從 i 到 n-1都是無序元素,所以當j < n 時,進行迴圈。由此推出第二層迴圈 for (int j = i+1; j < n; j++)。如果一層for迴圈從1開始的,自行調整一下即可。
至此我們就能寫出完整的選擇排序**了。嗯?不對,還有個問題,我們的min該等於什麼,嗯,沒錯,min = i,就可以了。
好了現在我們開始寫最後的**吧
1 void sort(int *arr, int count)
2 12 }
13 if (min != i) //為了避免arr[i],本身就是最小值任然進行交換的情況 。
14
19 }
20 }
view code
現在我們來想一想如何優化一下選擇排序,其實很明顯了,在交換方面我們已經沒有辦法優化了(至少對我這個蒟蒻來說)。那麼我們來思考一下,選擇排序每次選出最小的放在最前面,或者選出最大的放在最前。我們不僅可以選出最小的也可以選出最大,所以我們就在選出最小值的同時選出最大值,比較所消耗的時間要比迴圈少,略有優化。
按照這個思想可以寫出**如下:
1 void sort(int *arr, int count)
2 18 if (arr[max] < arr[i])
19
22 }
23 24 if (left != min) //最小交換
25
29 30 if (max == left) //防止當min最小,max最大時產生連續交換
31
34 35 if (right != max) //最大交換
36
41 left++;
42 right--;
43 }
44 }
view code
這裡要特別說明一下這段**
if (max == left)
為什麼一定要寫這段**呢,
我們 來看個例子 :
有個陣列其元素為 9 1 5 6 0;
max = 0,min = 4;
執行min交換後,0 1 5 6 9;
max = 0,min = 4;
這時候如果執行max迴圈那麼,陣列就和沒有執行min交換一樣
所以為了防止出現這種情況就需要加上這塊**。
目前作為蒟蒻的我只能優化到這裡,如果有更好的優化,大家自行探索,我也會慢慢學習,繼續更新。
排序演算法學習整理二(選擇)
二 選擇排序 選擇排序十分的簡單和直觀,其的工作原理是每一次從待排序的陣列中選出最小 或最大 的乙個元素,存放在序列的起始位置。因此,選擇排序也是像我們這種萌新最容易寫出來的排序演算法。排序步驟 選出最小的元素 放在陣列最前面 選出第二小的元素 放在第二位 重複如此直到完成排序 下面舉個栗子 有乙個...
排序演算法學習筆記整理
1 氣泡排序 依次比較相鄰元素的值,若發現逆序則交換,使值較大的元素逐漸從前移向後部 或者後部 2 選擇排序 以首元素開始為要交換的元素,迴圈找到未排序的元素中最小的元素與要交換的元素進行交換。要交換元素為未排序元素的第乙個,每次加一。主要 3 插入排序 把待排序的元素看成 以第乙個元素看成乙個無序...
排序演算法學習系列 選擇排序
選擇排序是最簡單直觀的一種演算法,基本思想為每一趟從待排序的資料元素中選擇最小 或最大 的乙個元素作為首元素,直到所有元素排完為止,簡單選擇排序是不穩定排序,平均時間複雜度為o n 2 o n 2 o n2 主要思路 在演算法實現時,每一趟確定最小元素的時候會通過不斷地比較交換來使得首位置為當前最小...