經過比較來決定元素間的相對次序,因爲其時間複雜度不能突破O(nlogn),所以也稱爲非線性時間比較類排序。ios
排序方法 | 時間複雜度(平均) | 時間複雜度(最壞) | 時間複雜度(最好) | 空間複雜度 | 穩定性 |
---|---|---|---|---|---|
冒泡排序 | O(n^2) | O(n^2) | O(n) | O(1) | 穩定 |
快速排序 | O(nlog2n) | O(n^2) | O(nlog2n) | O(n) | 不穩定 |
插入排序 | O(n^2) | O(n^2) | O(n) | O(1) | 穩定 |
希爾排序 | O(n^1.3) | O(n^2) | O(n) | O(1) | 不穩定 |
選擇排序 | O(n^2) | O(n^2) | O(n^2) | O(1) | 不穩定 |
堆排序 | O(nlog2n) | O(nlog2n) | O(nlog2n) | O(1) | 不穩定 |
歸併排序 | O(nlog2n) | O(nlog2n) | O(nlog2n) | O(n) | 穩定 |
介紹:
冒泡排序是一種簡單的排序算法。它重複地走訪過要排序的數列,一次比較兩個元素,若是它們的順序錯誤就把它們交換過來。走訪數列的工做是重複地進行直到沒有再須要交換,也就是說該數列已經排序完成。這個算法的名字由來是由於越小的元素會經由交換慢慢「浮」到數列的頂端。web
算法描述:算法
重複步驟1~3,直到排序完成。
shell
#include <iostream> using namespace std; int bubbleSort(int arr[],int n) { for (int i = 0; i < n - 1; i++) { for (int j = 0; j < n - i - 1; j++) { if (arr[j] > arr[j + 1]) { int temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } return 0; } int main() { int arr[1000]; int n; cout << "請輸入數組中元素的個數:"; cin >> n; cout << "請輸入元素: " << endl; for (int i = 0; i < n; i++) { cin >> arr[i]; } cout << "排序前:" << endl; for (int i = 0; i < n; i++) { cout << arr[i] << " "; } cout << endl; bubbleSort(arr, n); cout << "排序後:" << endl; for (int i = 0; i < n; i++) { cout << arr[i] << " "; } cout << endl; return 0; }
運行結果以下:
固然,咱們能夠再優化一下冒泡排序:數組
int bubbleSort(int arr[],int n) { for (int i = 0; i < n - 1; i++) { bool flag = true; for (int j = 0; j < n - i - 1; j++) { if (arr[j] > arr[j + 1]) { flag = false; int temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } if (flag) { break; } } return 0; }
這樣,當後面已經排序好了的狀況下,咱們就不須要再去遍歷後面的元素了。數據結構
#include <iostream> using namespace std; int swap(int *a, int *b) { int temp = *a; *a = *b; *b = temp; return 0; } int quicksort(int arr[], int left, int right) { if (left >= right) { return 0; } int i = left; int j = right + 1; int key =arr[left];//設置基準值 while (true) { //從左向右找比key大的值 while (arr[++i] < key && i != right); //從右向左找比key小的值 while (arr[--j] > key && j != left); if (i >= j) { break; } //交換ij對應的值 swap(&arr[i], &arr[j]); } //將基準值(中樞值)與j所對應的值交換,由於arr[J]是小於基準中下標最大的 swap(&arr[left], &arr[j]); quicksort(arr, left, j - 1); quicksort(arr, j + 1, right); return 0; } int main() { int arr[1000]; int n; cout << "請輸入數組中元素的個數:"; cin >> n; cout << "請輸入元素: " << endl; for (int i = 0; i < n; i++) { cin >> arr[i]; } cout << "排序前:" << endl; for (int i = 0; i < n; i++) { cout << arr[i] << " "; } cout << endl; quicksort(arr, 0, n - 1); cout << "排序後:" << endl; for (int i = 0; i < n; i++) { cout << arr[i] << " "; } cout << endl; return 0; }
運行結果以下:
雖然咱們實現了快速排序,可是卻存在兩個問題:ide
解決以上問題的方法:svg
代碼演示:函數
#include <iostream> #include <algorithm> using namespace std; //交換 int swap(int *a, int *b) { int temp = *a; *a = *b; *b = temp; return 0; } //簡單插入排序 int insertsort(int arr[], int n) { int temp, i, j; for (i = 1; i < n; i++) { temp = arr[i]; for (j = i; j > 0 && arr[j - 1] > temp; j--) { arr[j] = arr[j - 1]; } arr[j] = temp; } return 0; } //得到基準值 int median3(int arr[], int left, int right) { int center = (left + right) / 2; if (arr[left] > arr[center]) { swap(&arr[left], &arr[center]); } if (arr[left] > arr[right]) { swap(&arr[left], &arr[right]); } if (arr[center] > arr[right]) { swap(&arr[center], &arr[right]); } //此時arr[left]<arr[center]<arr[right] swap(&arr[center], &arr[right - 1]);//已知arr[right]>arr[center] return arr[right - 1];//只需考慮arr[left+1]到arr[right-2]的值,因此返回arr[right-1] } //快排 int quicksort(int arr[], int left, int right) { int key, i, j; if (right - left > 3)//當元素較多時調用快速排序 { key = median3(arr, left, right);//選擇基準 i = left; j = right - 1; while (true) { while (arr[++i] < key);//從左向右找比key大的值 while (arr[--j] > key);//從右向左找比key小的值 if (i > j) { break; } swap(&arr[i], &arr[j]); } swap(&arr[i], &arr[right - 1]);//將基準值與按順序第一個大於基準值的元素交換,保證前面小於後面大於基準 quicksort(arr, left, i - 1);//遞歸解決左邊的 quicksort(arr, i + 1, right);//遞歸解決右邊的 } else//當元素較少時,直接用簡單插入排序 { insertsort(arr + left, right - left + 1); } return 0; } int main() { int arr[1000]; int n; cout << "請輸入數組中元素的個數:"; cin >> n; cout << "請輸入元素: " << endl; for (int i = 0; i < n; i++) { cin >> arr[i]; } cout << "排序前:" << endl; for (int i = 0; i < n; i++) { cout << arr[i] << " "; } cout << endl; quicksort(arr, 0, n - 1); cout << "排序後:" << endl; for (int i = 0; i < n; i++) { cout << arr[i] << " "; } cout << endl; return 0; }
運行結果以下:
優化
#include <iostream> using namespace std; int insertionSort(int arr[], int n) { int temp, i, j; for (i = 1; i < n; i++) { temp = arr[i]; for (j = i; j > 0 && arr[j - 1] > temp; j--) { arr[j] = arr[j - 1]; } arr[j] = temp; } return 0; } int main() { int arr[1000]; int n; cout << "請輸入數組中元素的個數:"; cin >> n; cout << "請輸入元素: " << endl; for (int i = 0; i < n; i++) { cin >> arr[i]; } cout << "排序前:" << endl; for (int i = 0; i < n; i++) { cout << arr[i] << " "; } cout << endl; insertionSort(arr, n); cout << "排序後:" << endl; for (int i = 0; i < n; i++) { cout << arr[i] << " "; } cout << endl; return 0; }
運行結果以下:
#include <iostream> using namespace std; int shellSort(int arr[], int n) { for (int gap = n / 2; gap > 0; gap--)//肯定增量 { for (int i = gap; i < n; i += gap)//每次都間隔增量,將這些排序 { int temp = arr[i]; int j; for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) { arr[j] = arr[j - gap]; } arr[j] = temp; } } return 0; } int main() { int arr[1000]; int n; cout << "請輸入數組中元素的個數:"; cin >> n; cout << "請輸入元素: " << endl; for (int i = 0; i < n; i++) { cin >> arr[i]; } cout << "排序前:" << endl; for (int i = 0; i < n; i++) { cout << arr[i] << " "; } cout << endl; shellSort(arr, n); cout << "排序後:" << endl; for (int i = 0; i < n; i++) { cout << arr[i] << " "; } cout << endl; return 0; }
運行結果以下:
#include <iostream> using namespace std; int selectionSort(int arr[], int n) { for (int i = 0; i < n; i++) { int minIndex = i; for (int j = i + 1; j < n; j++) { if (arr[minIndex] > arr[j]) { minIndex = j; } } int temp = arr[minIndex]; arr[minIndex] = arr[i]; arr[i] = temp; } return 0; } int main() { int arr[1000]; int n; cout << "請輸入數組中元素的個數:"; cin >> n; cout << "請輸入元素: " << endl; for (int i = 0; i < n; i++) { cin >> arr[i]; } cout << "排序前:" << endl; for (int i = 0; i < n; i++) { cout << arr[i] << " "; } cout << endl; selectionSort(arr, n); cout << "排序後:" << endl; for (int i = 0; i < n; i++) { cout << arr[i] << " "; } cout << endl; return 0; }
運行結果以下:
#include <iostream> #include <algorithm> using namespace std; int percDown(int arr[], int p, int n)//創建最大堆 { int parent, child;//標記根結點和孩子結點 int x; x = arr[p]; for (parent = p; (parent * 2 + 1) < n; parent = child) { child = parent * 2 + 1;//得到孩子結點的下標 if ((child != n - 1) && (arr[child] < arr[child + 1])) { child++;//指向左右子結點的較大者 } if (x >= arr[child])//找到合適的位置,即根結點大於子結點 { break; } else { arr[parent] = arr[child];//反之交換 } } arr[parent] = x; return 0; } int swap(int *x, int *y)//交換 { int temp = *x; *x = *y; *y = temp; return 0; } int heapSort(int arr[], int n)//堆排序 { for (int i = n / 2 - 1; i >= 0; i--) { percDown(arr, i, n);//創建最大堆 } for (int i = n - 1; i > 0; i--) { swap(&arr[0], &arr[i]);//將最大堆中的最大值放在arr[i] percDown(arr, 0, i);//而後用0-i建立最大堆獲取最大值,即刪除最大堆頂 } return 0; } int main() { int arr[1000]; int n; cout << "請輸入數組中元素的個數:"; cin >> n; cout << "請輸入元素: " << endl; for (int i = 0; i < n; i++) { cin >> arr[i]; } cout << "排序前:" << endl; for (int i = 0; i < n; i++) { cout << arr[i] << " "; } cout << endl; heapSort(arr, n); cout << "排序後:" << endl; for (int i = 0; i < n; i++) { cout << arr[i] << " "; } cout << endl; return 0; }
運行結果以下:
#include <iostream> using namespace std; //將arr[left]-arr[center-1]和arr[center]-arr[right]歸併成一個序列 int merge(int arr[], int tmparr[], int left, int center, int right) { int l_end = center - 1;//左邊終點的位置 int tmp = left;//有序序列的起始位置 int len = right - left + 1;//總長度 while (left <= l_end && center <= right) { if (arr[left] <= arr[center])//將小的元素先複製到tmparr中 { tmparr[tmp++] = arr[left++];//將左邊的元素複製到tmparr中 } else { tmparr[tmp++] = arr[center++];//將右邊的元素複製到tmparr中 } } while (left <= l_end)//直接將左邊剩下的全部元素都複製到tmparr中 { tmparr[tmp++] = arr[left++]; } while (center <= right)//直接將右邊剩下的全部元素都複製到tmparr中 { tmparr[tmp++] = arr[center++]; } //將有序的tmparr複製回arr中 for (int i = 0; i < len; i++,right--) { arr[right] = tmparr[right]; } return 0; } int msort(int arr[], int tmparr[], int left, int right) { int center; if (left < right) { center = (left + right) / 2; msort(arr, tmparr, left, center);//遞歸解決左邊 msort(arr, tmparr, center + 1, right);//遞歸解決右邊 merge(arr, tmparr, left, center + 1, right);//合併兩段有序序列並排序 } return 0; } int mergeSort(int arr[], int n) { int *tmparr; //建立一個數組,以便歸併 tmparr = (int *)malloc(n * sizeof(int)); if (tmparr != NULL) { msort(arr, tmparr, 0, n - 1); //釋放空間 free(tmparr); } else { cout << "空間不足" << endl; } return 0; } int main() { int arr[1000]; int n; cout << "請輸入數組中元素的個數:"; cin >> n; cout << "請輸入元素: " << endl; for (int i = 0; i < n; i++) { cin >> arr[i]; } cout << "排序前:" << endl; for (int i = 0; i < n; i++) { cout << arr[i] << " "; } cout << endl; mergeSort(arr, n); cout << "排序後:" << endl; for (int i = 0; i < n; i++) { cout << arr[i] << " "; } cout << endl; return 0; }
運行結果以下: