寫在前面:
排序又稱為分類,它是資料處理中經常用到的一種重要運算。
雖然並未列入世界最偉大的幾大演算法之一,但毫無疑問,在各行各業的各個時期排序都是作為奠基者般的存在為程式所呼叫,也為程式設計者所敬仰。只是,也許正是因為它與我們息息相關,以至於我們竟然時常忽略它的存在。
事實上我們生活中無時無刻不在做排序:考試成績排名,按身高、年齡、能力高低去評判他人,劃分任務處理的優先順序,等等·······
為簡單起見,我們採用順序儲存的結構存放所排序的資料元素序列。
雖然簡單選擇排序與簡單插入排序都是「簡單的排序」,但是我們好奇的是:它們的思想和實現有什麼區別呢?
我們已經知道,所謂簡單插入排序,就是將所有待排序元素分為有序無序兩個部分,每次取出無序部分的第乙個元素,通過資料比較,插入到有序序列的合適位置,依次類推直到所有資料有序,它是乙個穩定的演算法。
而簡單選擇排序,重在「選擇」二字,怎麼個選法呢?
大家試想一下公司(比如谷歌)是如何選擇招聘優秀員工的?
在一群(無序的)應聘者中,首先把表現最好(排序碼最小)的員工挑出來(形成有序部分的第乙個元素),然後在剩下的所有員工中再選出表現最後的(放入到有序部分的第二個位置),以此類推直到選出所有公司需要的職員。
相信這一流程非常容易理解,因為它很符合人類的思維(但有缺點,缺點後面詳述)。
我們將簡單選擇排序的思想規範化描述一下:第一趟排序是在無序的中按排序碼選出最小的元素,將它與r1交換;第二趟排序是在無序的中選出最小的元素,將它與r2交換;而第i趟排序時已排好序,在當前無序的中再選出最小的元素,將它與ri交換,使有序。值得注意的是,i-1趟排序後,整個資料元素就是遞增有序的(為什麼?)
我們可以給出乙個簡單選擇排序的c語言描述(假設待排序元素為double型資料):
void selectsort1(double a,int n)
}a[i] = small; //it is the ith smallest element}}
以上**經測試(此處略)實現了遞增排序,但是我們注意到有乙個問題:它可能要多次交換資料,即a[j]與small,而它並沒有對我們的排序結果(根據這一排序演算法)做出實際貢獻。這勢必會導致整體執行效率的低下。那麼有沒有改良的方案呢?
有。我們考慮不移動資料,只把排序碼做個變化,**如下:
void selectsort2(double a,int n)
if (i != small) }}
這樣一來,交換資料的動作在最壞情況下也就只需n-1個,大大減少了交換所需的開銷。
簡單評估一下簡單選擇排序:
函式selectsort中外層for迴圈需執行n-1次,而對於找出排序碼最小的資料元素的內層for迴圈,最壞情況下需要執行n-i次資料比較,因此簡單選擇排序最壞情況下需要執行n-1+n-2+…1 = n(n-1)/2次比較,演算法效率為o[n^2](注意,與簡單插入排序效率等級相同)。
如此一來,我們有了乙個疑問,乙個是簡單選擇排序,乙個是簡單插入排序,這兩種「簡單排序」誰更快呢?
有人會想,應該是一樣快吧,畢竟演算法效率都一樣。
非也非也,是騾子是馬,牽出來遛遛。我們用**進行測試(包括針對第一種不完善的簡單選擇排序的測試),測試**如下:
#include "stdio.h"
#include "stdlib.h"
#include "time.h"
void print(double a,int n);
void selectsort1(double a,int n);
void selectsort2(double a,int n);
void insertsort(double a,int n);
#define num 20000
int main(int argc, char* argv)
void print(double a,int n)
printf("\n");
}void selectsort1(double a,int n)
}a[i] = small; //it is the ith smallest element
}}void selectsort2(double a,int n)
if (i != small)
}}void insertsort(double a,int n)
a[j+1] = temp; //insert element temp}}
測試大量(**中是20000,可更改)資料的結果如下圖(不妨多測幾次,排除干擾):
三次測試中,我們發現:對於相同的資料樣本,簡單插入排序的效果每次都好於簡單選擇排序。這說明,實際上簡單插入排序演算法平均效率最高(而不是最壞情況下效率最高,我們有理由相信,最壞情況下簡單選擇排序與簡單插入排序演算法效率相等或相近)。
至於為什麼,乙個直覺的答案是:簡單插入排序是穩定的,而簡單選擇排序則不穩定(為什麼?)。
to be continued…
排序演算法(二)簡單選擇排序
一 介紹 1 氣泡排序的基本思想就是不斷地比較 交換,通過交換完成最終的排序 而相比氣泡排序來說,選擇排序法的基本思想是在排序時找到合適的關鍵字再做交換,且只移動一次就完成相應關鍵字的排序定位,也就是說每一趟在n i 1 i 1,2.n 1 個記錄中選取關鍵字最小的記錄作為有序序列的第i個記錄。二 ...
排序演算法 選擇排序 簡單選擇排序
package 選擇排序 簡單選擇排序 不穩定 基本思想 在要排序的一組數中,選出最小的乙個數與第乙個位置的數交換 然後在剩下的數當中再找最小的與第二個位置的數交換,如此迴圈到倒數第二個數和最後乙個數比較為止。public class 簡單選擇排序 system.out.println 排序之前 f...
排序演算法 簡單選擇排序
簡單選擇排序是一種選擇排序。1.簡單選擇排序的定義 每趟從待排序的記錄中選出關鍵字最小的記錄,順序放在已排序的記錄序列末尾,直到全部排序結束為止。2.簡單選擇排序的流程 例項 注 紅色數字是位置發生變化的數值。3.簡單選擇排序的 實現 public class selectsort 若min有變化,...