對於非比較排序算法,如計數排序、基數排序,你們若是感興趣,能夠查看博客http://10740184.blog.51cto.com/10730184/1782077。本文,我將介紹比較排序算法。
算法
直接插入排序:數組
在序列中,假設升序排序ide
1)從0處開始。優化
1)若走到begin =3處,將begin處元素保存給tmp,比較tmp處的元素與begin--處元素大小關係,若begin處<begin-1處,將begin-1處元素移動到begin;若大於,則不變化。再用tmp去和begin--處的元素用一樣的方法去做比較,直至begin此時減小到數組起始座標0以前結束。ui
3)以此類推,依次走完序列。spa
時間複雜度:O()
設計
代碼以下:blog
//Sequence in ascending order void InsertSort(int* a,int size) { assert(a); for (int begin = 0; begin < size ; begin++) { int tmp = a[begin]; int end = begin-1; while (end >= 0 && tmp < a[end]) { a[end+1] = a[end]; a[end] = tmp; end--; } } }
2.希爾排序排序
希爾排序其實是直接插入排序的優化和變形。假設升序排序遞歸
1)咱們先去取一個增量值gap,將序列分爲幾組。
2)而後咱們分組去排序。當每一個分組排序排好後,至關於整個序列的順序就排列好了。
3)比較a[i],a[i+gap]大小關係,若a[i]>a[i+gap],則交換。不然不處理。日後走,繼續該步驟……
代碼以下:
//Sequence in ascending order void ShellSort(int* a, int size) { assert(a); int gap = size; while (gap > 1) { gap = gap / 3 + 1; for (int i = 0; i < size - gap; i++) { int end = i; int tmp = a[end + gap]; while (end >= 0 && a[end] > a[end + gap]) { a[end+gap] = a[end]; a[end] = tmp; end -= gap; } } } }
3.選擇排序
假設升序排序
1)第1次遍歷整個數組,找出最小(大)的元素,將這個元素放於序列爲0(size-1)處。此時,未排序的序列不包括0(size-1)處.第2次,一樣的方法找到找到剩下的未排序的序列中的最小的元素,放於序列爲1處。
2)重複,直至排到序列結尾處,這個序列就排序好了。
時間複雜度:O(N^2)。
代碼以下:
//Sequence in ascending order void SelectSort(int* a, int size) { assert(a); for (int i = 0; i < size; i++) { int minnum = i; for (int j = i+1; j < size;j++) { if (a[minnum] > a[j]) { minnum = j; } } if (i != minnum) { swap(a[i], a[minnum]); } } }
4.堆排序
假設升序排序
咱們先要思考升序序列,咱們須要建一個最大堆仍是最小堆?
若是最小堆,那麼每一個根節點的元素大於它的子女節點的元素。可是,此時卻不能保證她的左右節點必定哪一個大於哪個,且不能保證不一樣一層的左右子樹的節點元素大小。
因此,要設計升序排序,咱們須要建一個最大堆。
1)建一個最大堆。
2)第1次,將根節點的元素與堆的最後一個節點元素交換,這樣確定保證最大元素在堆的最後一個節點處,而後此時的根節點並不必定知足大於左右子女節點,所以將其向下調整,至合適位置處。第2次,將根節點的元素與堆的倒數第2個節點元素交換,向下調整交換後的根節點至合適位置……
代碼以下:
void _AdjustDown(int parent, int* a, int size) { int child = 2 * parent + 1; while (child < size) { if (child + 1 < size && a[child + 1] > a[child]) { child++; } if (a[child] >a[parent]) { swap(a[child], a[parent]); parent = child; child = 2 * parent + 1; } else { break; } } } //Sequence in ascending order void HeapSort(int* a, int size) { assert(a); for (int i = (size - 2) / 2; i >= 0;i--) { _AdjustDown(i, a, size); } for (int i = 0; i < size -1; i++) { swap(a[0], a[size - i -1]); _AdjustDown(0, a, size-i-1); } }
5.冒泡排序
假設升序排序
冒泡,顧名思義,像泡同樣慢慢地沉。
1)第一次,比較a[0],a[1]大小,若a[0]>a[1],則交換它們。再比較a[1],a[2],若a[1]>a[2],則交換……這樣一直到比較a[size-1],a[size]結束,此時已經將一個最大的元素沉到序列的最尾端size-1處了。
2)第二次,重複上述操做,可將次最大的元素沉到size-2處。
3)重複,完成排序。
比較:
冒泡排序是兩兩比較,每次將最大的元素日後沉。而選擇排序不一樣的是,每次遍歷選擇出最大元素放到最後。
代碼以下:
//Sequence in ascending order void BubbleSort(int* a, int size) { assert(a); for (int i = 0; i < size; i++) { for (int j = 0; j < size - i -1; j++) { if (a[j] > a[j + 1]) { swap(a[j], a[j + 1]); } } } }
6.快速排序
快速排序,顧名思義,排序算法很快,它是最快的排序。時間複雜度爲:O(n*lgn).適合於比較亂的 序列。假設升序排序
這兩種方法都挺簡單的,相比而言,方法2代碼更短,更加簡單!!!你們本身斟酌使用!!!
方法1:
咱們這裏先介紹快速排序的挖坑法。(每次數據被挪走後都至關於挖出了一個坑,這個坑能夠把其餘數據挪過來放。)
對於序列:{ 5, 1,8,12, 19, 3, 7, 2, 4 ,11}
1)咱們取序列的第一個數據當作比較的基準,而且設定序號爲0的位置爲低位置low,序號爲size-1的位置爲高位置high。
2)取出序列的基準元素key,此刻的5.
在high位置從右往左找直到找到比基準值5小的元素,即此刻的元素4處中止。
而後,在low位置從左往右找直到找到比基準值5大的元素,即此刻的元素8中止。
因爲此時的基準元素key被取出,存放它的位置就空下來了。將找到的元素4賦值給此刻的這個位置.
3)此時元素4存放的位置空下來了,將找到的低位置的8放到這個位置去。
4)重複這樣的動做,2放到基準位置,12放到原來2的位置……
5)直到low>=high時中止。
以上是一次快速排序,在通過一次快速排序後,high與low相遇左右各造成有序序列。再將這個相遇位置左右各當成一個序列,繼續進行快速排序,最終能夠將序列排序好。
代碼以下:
void QuickSort(int* a, int left,int right) { assert(a); int low = left; int high = right; int key = a[low]; while (low < high) { while (low < high && key <= a[high]) { high--; } a[low] = a[high]; while (low <high && key >= a[low]) { low++; } a[high] = a[low]; } a[low] = key; if (left <= high) { QuickSort(a, left, low - 1); QuickSort(a, low + 1, right); } }
方法2:
快速排序的prev、cur法:
爲了方便給你們分享,我把它稱之爲prev、cur法。
1)引入兩個位置,prev、cur,cur首先指向序列的初始位置,prev指向cur的前面(即:若cur=0,則prev=-1位置處)。
2)咱們將基準key取成序列的最後一個位置right處的元素。
3)cur從初始位置處開始,(由於要排成升序),找一個cur處的值大於key的值中止,不然小於key的值的話,就一直繼續cur往前走,此時prev是不動的。可是當找到cur處的值大於key的值時,++prev,再將prev處的值與cur的值進行交換。(注意,prev前置加加,即prev先日後走一步再交換值)。
4)cur繼續往前走,繼續重複第3)條步驟,直到遇到right-cur=1,立刻就要相交時中止。
5)中止後,遞歸左右區間,重複上述步驟,直至區間只剩下一個元素時無需繼續劃分區間遞歸,排序結束。
代碼以下:
int QuickSort(int* a, int left, int right) { assert(a); int cur = left; int prev = cur - 1; int key = mid(a,left,right); swap(key, a[right]); while (cur < right) { if (a[cur] <= a[right]) { swap(a[++prev], a[cur]); } cur++; } swap(a[++prev], a[right]); if (prev - 1 > left) { QuickSort(a, left, prev - 1); } if (prev + 1 < right) { QuickSort(a, prev + 1, right); } }