[數據結構(二)]七種排序算法的C++簡單實現
一.冒泡排序(Bubble Sort)
基本思想:兩兩比較相鄰記錄的關鍵字,如果反序則交換,直到沒有反序的記錄為止。
//冒泡排序 void BubbleSort(int *p, int length) { for (int i = 0; i < length-1; i++) { for (int j =length-1; j>=i;j--) { if (p[j-1] > p[j]) { swap(p[j-1], p[j]); } } } }
排序前的順序為:9 1 5 8 3 7 4 6 2
當i=1時,交換的情況如下:
二.簡單選擇排序(Simple Selection Sort)
通過n-1次關鍵字間的比較,從n-i+1個記錄中選擇最小的記錄,並和第i次(1≤i≤n)記錄交換。
//簡單選擇排序 void SimSelSort(int *p, int length) { int i, j, min; for (i = 0; i < length - 1; i++) { min = i; //記錄最小值的下標,初始化為i for(j=i+1;j<=length-1;j++) { if (p[j] < p[min]) min = j; //通過不斷地比較,得到最小值的下標 } swap(p[i], p[min]); } }
三.直接插入排序
把一個記錄直接插入到已經排好序的有序表中,從而得到一個新的,記錄數增1的有序表。
//直接插入排序 void StrInserSort(int *p, int length) { int i, j; for (i =1; i <length; i++) {if ( p[i]<p[i-1]) { int tmp; tmp = p[i]; for (j = i - 1; p[j] > tmp; j--) p[j+1] = p[j]; p[j+1] = tmp; } } }
四.希爾排序(Shell Sort)
希爾排序是把記錄按下標的一定增量分組,對每組使用直接插入排序算法排序;隨著增量逐漸減少,每組包含的關鍵詞越來越多,當增量減至1時,整個文件恰被分成一組,算法便終止。
void ShellSort(int *p, int length) { int i, j; int increment = length; do { increment = increment / 3 +1; for (i = increment ; i <= length - 1; i++) { if (p[i] < p[i - increment]) { int tmp; tmp = p[i]; for (j = i - increment; j >= 0 && tmp < p[j]; j -= increment) p[j + increment] = p[j]; p[j + increment] = tmp; } } } while (increment > 1); }
五.堆排序(Heap Sort)
1.堆的定義
堆是具有下列性質的完全二叉樹:每個結點的值都大於或等於其左右孩子結點的值,稱為大頂堆;或者每個結點的值都小於或等於其左右孩子結點的值,稱為小頂堆。
2.堆排序
堆排序的基本思想(利用堆,如大頂堆進行排序):將待排序的序列構造成一個大頂堆。此時,整個序列的最大值就是堆頂的根結點。將它移走(其實就是將它與堆數組的末尾元素交換,此時末尾元素就是最大值),然後將剩余n-1個序列重新構造成一個堆,這樣就會得到n個元素的次小值。如此反復執行,便能得到一個有序序列。
主要問題:
1.如何由一個無序序列構建成一個堆?
2.如何在輸出堆頂元素後,調整剩余元素成為一個新的堆?
//構造最大堆 void MaxHeapFixDown(int *p, int i, int length) { int j = 2 * i + 1; int temp = p[i]; while (j<length) { if (j + 1<length && p[j]<p[j + 1]) ++j; if (temp>p[j]) break; else { p[i] = p[j]; i = j; j = 2 * i + 1; } } p[i] = temp; } //堆排序 void HeapSort(int *p, int length) { for (int i = length / 2 - 1; i >= 0; i--) { MaxHeapFixDown(p, i, length); } for (int i = length - 1; i >= 1; i--) { swap(p[i], p[0]); MaxHeapFixDown(p, 0, i); cout << "i的值:" << i << " 排序:"; ergodic(p, 9); } }
六.歸並排序(Merging Sort)
歸並排序就是利用歸並思想實現的排序方法。原理:假設初始序列含有n個記錄,則可以看成是n個有序的子序列,每個子序列長度為1,然後再兩兩歸並,得到[n/2]個長度為2或1的有序子序列;再兩兩歸並….,如此重復,直到的一個長度為n的有序序列為止,稱為2路歸並排序。
七.快速排序(Quick Sort)
快速排序的基本思想是:通過一趟排序將待排記錄分割成獨立的兩部分,其中一部分記錄的關鍵字均比另外一部分記錄的關鍵字小,則可分別對這兩部分記錄繼續進行排序,以達到整個序列有序的目的。
//快速排序 void QuickSort(int *p, int l, int r) { if (l< r) { int i = l, j = r, x = p[l]; while (i < j) { while (i < j && p[j] >= x) // 從右向左找第一個小於x的數 j--; if (i < j) p[i++] = p[j]; while (i < j && p[i]< x) // 從左向右找第一個大於等於x的數 i++; if (i < j) p[j--] = p[i]; } p[i] = x; QuickSort(p, l, i - 1); // 遞歸調用 QuickSort(p, i + 1, r); } }
總結
參考:《大話數據結構》
[數據結構(二)]七種排序算法的C++簡單實現