趁著有時間把學習過的排序演算法又實現了一遍複習一下,實現的排序演算法主要有以下幾種:氣泡排序、快速排序,選擇排序,堆排序,插入排序,合併排序,希爾排序,桶排序等。
下面排序的都是vector,懶得寫模板了
1.氣泡排序
氣泡排序是最簡單的排序演算法,氣泡排序的基本思想是從後往前(或從前往後)兩兩比較相鄰元素的值,若為
逆序,則交換它們,直到序列比較完。我們稱它為一趟冒泡。每一趟冒泡都會將一
個元素放置到其最終位置上。
//2.快速排序氣泡排序
void bubblesort(vector &vec)}}
快速排序是對氣泡排序的一種改進。其基本思想是基於分治法:在待排序表l[n]
中任取乙個元素pivot作為基準,通過一趟排序將序列劃分為兩部分l[1...k-1]和
l[k+1...n],是的l[1...k-1]中的所有元素都小於pivot,而l[k+1...n]中所有元素
都大於或等於pivot。則pivot放在了其最終位置l(k)上。然後,分別遞迴地對兩個子
序列重複上述過程,直至每部分內只有乙個元素或空為止,即所有元素放在了其最終
位置上。
劃分為兩個部分
int partition(vector &vec, int left, int
right)
vec[left] = base
;
return
left;
}void quicksort(vector &vec, int left, int
right)
}3.簡單選擇排序對要排序的序列,選出關鍵字最小的資料,將它和第乙個位置的資料交換,接著,選出關鍵字次小的資料,將它與第二個位置上的資料交換。以此類推,直到完成整個過程。
所以如果有n個資料,那麼則需要遍歷n-1遍。
void selectsort(vector &vec)4.直接插入排序為了實現n個數的排序,將後面n-1個數依次插入到前面已排好的子串行中,假定剛開始第1個數是乙個已排好序的子串行,那麼經過n-1趟就能得到乙個有序序列。if (minpos !=i)}}
void insertsort(vector &vec)5.希爾排序希爾排序(shell sort)是插入排序的一種,是對直接插入排序演算法的改進該方法又稱縮小增量排序。希爾排序通過比較相距一定間隔的元素,即形如l[i,i+d,i+2d,...i+kd]的序列然後縮小間距,再對各分組序列進行排序。直到只比較相鄰元素的最後一趟排序為止,即最後的間距為1。vec[j + 1] =tmp;}}
}6.合併排序合併排序採用分治法,思路是將兩個或以上的有序表合併為乙個有序表,把待排序的序列分割為若干個子串行,每個子串行有序,然後再把子序列合併為乙個有序序列。若將兩個有序表合併成乙個有序表,則成為2路合併排序。
2-路歸併就是將2個有序表組合成乙個新的有序表。假定待排序表有n個元素,則可以看成是n個有序的子表,每個子表長度為1,然後兩兩歸併...不停重複,直到合成乙個長度為n的有序序列為止。merge()函式是將前後相鄰的兩個有序表歸併為乙個有序表,設a[low...mid]和a[mid+1...high]存放在同一順序表的相鄰位置上,先將它們複製到輔助陣列b中。每次從對應b中的兩個段取出乙個元素進行比較,將較小者放入a中。
將兩個有序序列vec[low..mid] vec[mid..high]合併
void merge(vector &vec, vector &tmparray, int low, int mid, int
high)
while (i <=m)
while (j <=n)
for (i = 0; i < k; ++i)
}void mergesort(vector &vec, vector &tmparray, int low, int
high)
}void mergesort(vector &vec)
7.堆排序堆排序是一種樹形選擇排序方法,在排序過程中,將l[n]看成是一棵完全二叉
樹的順序儲存結構,利用完全二叉樹中雙親節點和孩子節點之間的內在關係,在當
前無序區中選擇關鍵字最大(或最小)的元素。堆排序的思路是:首先將序列l[n]
的n個元素建成初始堆,由於堆本身的特點(以大根堆為例),堆頂元素就是最大
值。輸出堆頂元素後,通常將堆底元素送入堆頂,此時根結點已不滿足大根堆的性
質,堆被破壞,將堆頂元素向下調整使其繼續保持大根堆的性質,再輸出堆頂元素。
如此重複,直到堆中僅剩下乙個元素為止。
使用陣列二叉樹 陣列實現的堆中,第n個節點的左孩子的索引值是(2n+1),右孩子的索引是(2n+2)
void heapadjust(vector &vec, int root, int
size)
}}void heapsort(vector &vec)
for (int i = size - 1; i > 0; --i)
}8.桶排序假設輸入是由乙個隨機過程產生的[0, 1)區間上均勻分布的實數。將區間[0, 1)劃分為n個大小相等的子區間(桶),每桶大小1/n:[0, 1/n), [1/n, 2/n), [2/n, 3/n),…,[k/n, (k+1)/n ),…將n個輸入元素分配到這些桶中,對桶中元素進行排序,然後依次連線桶輸入0 ≤a[1..n] <1輔助陣列b[0..n-1]是一指標陣列,指向桶(鍊錶)
9.基數排序
基數排序可以說是桶排序的一種改進和推廣,它不需要比較關鍵字的大小。它是根據關鍵字中各位的值,通過對排序的n個元素進行若干趟「分配」與「收集」來實現排序的。
由於比較簡單,這裡就不給出**了
10.計數排序
計數排序是乙個類似於桶排序的排序演算法,其優勢是對已知數量範圍的陣列進行排序。它建立乙個長度為這個資料範圍的陣列c,c中每個元素記錄要排序陣列中對應記錄的出現個數。基本思想是對於給定的輸入序列中的每乙個元素x,確定該序列中值小於x的元素的個數。一旦有了這個資訊,就可以將x直接存放到最終的輸出序列的正確位置上。
計數排序很快,o(n)的時間複雜度,但是我們平時還是用的很少,是因為它需要乙個至少等於待排序陣列取值範圍的緩衝區,而且通常只能用於正整數。
int max(vector &vec)return
max;
}void countsort(vector &vec)
int cur = 0, num = 0
;
while (cur
num++;}}
排序演算法總結
1 直接插入排序 1 穩定性 穩定 2 適用情況 待排記錄規模較小,或者記錄已經基本有序 2 希爾排序 1 穩定性 不穩定 2 特點 希爾排序的執行時間依賴於增量序列,它的效率比直接插入排序有較大的改進。3 氣泡排序 1 穩定性 穩定 2 特點 當待排記錄基本有序是,氣泡排序是不錯的選擇 但由於氣泡...
排序演算法總結
1 選擇排序 選擇排序的思想是依次從待排序數列中選擇最大 小 的 第二大 小 的等等,然後依次重新排列為有序數列。void selectionsort int a,int n if min i 時間複雜度o n 2 2 歸併排序 void merge int a,int left,int mid,i...
排序演算法總結
學習了這麼多的排序演算法,還沒有做個總結,呵呵 氣泡排序 氣泡排序是最慢的排序演算法。在實際運用中它是效率最低的演算法。它通過一趟又一趟地比較陣列中的每乙個元素,使較大的資料下沉,較小的資料上公升。它是 o n 2 的演算法。快速排序 快速排序是乙個就地排序,分而治之,大規模遞迴的演算法。從本質上來...