我們將討論對陣列和鍊錶的排序。我們關心的效能指標是排序演算法的執行時間和所消耗的額外記憶體空間。
定義:穩定——如果排序後檔案中具有相同關鍵字的元素的相對位置保持不變,稱乙個排序演算法是穩定的。
逆序——檔案中一對順序不對的元素稱為乙個逆序。
是思路非常簡單的一種排序演算法,工作過程如下:首先,選出陣列中最小的元素,將它與陣列中第乙個元素進行交換。然後找出次小的元素,將它與陣列中第二個元素進行交換……直到整個陣列排好序。**實現如下:
void selection(item a,int l,int r)
}
選擇排序的缺點是:它的執行時間對檔案中已有序的部分依賴較少。
原理:從序列中第二個數a[1]開始,每一步都將乙個待排資料a[i]按其大小插入到已排好序的資料中的適當位置,直到全部插入完畢。**實現如下:
如果沒有設定哨兵,那麼
void insertion(item a,int l,int r)
a[j]=v; //最後將該元素v放到正確的位置
}}
在這裡,「j>l」通常是為真,是無用的,它只在待插入元素是最小的且要插入到陣列最前端時才為假。為了省略該判斷條件,將陣列中最小元素提前放在第1個,並從l+2位開始插入:
void insertion(item a,int l,int r)
a[j]=v;
}}
注意,這裡設定最小元素為哨兵的目的,是為了省略while迴圈中的判斷條件「j>l」。
原理:遍歷陣列,如果近鄰的兩個元素大小順序不對,就將兩者交換,重複這樣的操作直到整個檔案排好序。假設從右到左進行,第一遍將最小的元素移到了最左邊,第二遍將第二小的元素移到了左邊第二位……氣泡排序實際上是一種選擇排序。
**實現如下:
void bubble(item a,int l,int r)
}}
希爾排序是插入排序的改進版本,實質就是分組插入排序,也叫作縮小步長排序。原理:先將整個檔案分割成若干個子檔案(由相隔某個步長的元素組成),分別進行直接插入排序,然後依次縮減步長再進行排序,待整個序列中的元素基本有序(步長足夠小)時,再對全體元素進行一次直接插入排序。因為直接插入排序在元素基本有序的情況下(接近最好情況)效率是很高的,因此希爾排序在時間效率上比插入排序有較大提高。
如何選用步長是個很難回答的問題,通常使用以幾何級別減少的序列。
如果在插入排序中不使用哨兵,並且用h代替1,就得到了h-排序的檔案。增加乙個外部迴圈來改變步長就實現了希爾排序。**實現如下:
void shell(item a,int l,int r)
a[j]=v;
}}
注意,這裡的步長間的比例大概是1/3,方法是從1開始,通過乘3加1得到下乙個步長。於是步長序列是1、4、13、40、121、364…… 冒泡 選擇 插入 希爾排序
include include include using namespace std template void print const t a,int n 氣泡排序 每次迴圈總是將最大元素移到隊尾 o n 2 穩定的排序演算法 templatevoid bubblesort t a,int n ...
排序演算法 冒泡 選擇 插入與希爾排序
思路分析 依次比較相鄰的兩個數 將比較小的數放在前面,比較大的數放在後面 第一趟比較完後,最小的數放在第一位 那麼在第二趟的時候不需要再對第一位數進行比較 依次類推,每一趟比較次數依次減小 c 實現 include using namespace std void show int arr,int ...
排序演算法及分析(插入 希爾 選擇 冒泡)
假如我們要從小到大排序,下面幾種簡單的演算法可以處理規模不大的資料,我寫成函式形式。一 插入排序 思想就是 從左到右對每個數,每次在它前面找到乙個合適的位置把它插進去。void insertsort int a,int n c是比較次數,m是移動次數,則 最好情況 c n 1 m 0 最壞情況 c ...