排序算法

来源:互联网 发布:python下载matplotlib 编辑:程序博客网 时间:2024/06/14 09:12

冒泡

复杂度O(n^2)


标准写法

void BubbleSort(vector<int> &a){int n = a.size();for (int i = 0; i < n; i++){for (int j = 0; j < n-i-1; j++){if (a[j] > a[j+1]){a[j] ^= a[j+1];a[j+1] ^= a[j];a[j] ^= a[j+1];}}}}
改进

用flag标记当前是否已经有序

void BubbleSort(vector<int> &a){int n = a.size();bool flag=true;for (int i = 0; i < n&&flag; i++){flag = false;for (int j = 0; j < n-i-1; j++){if (a[j] > a[j+1]){a[j] ^= a[j+1];a[j+1] ^= a[j];a[j] ^= a[j+1];flag = true;}}}}

简单写法,效率不高

void BubbleSort(vector<int> &a){int n = a.size();for (int i = 0; i < n; i++){for (int j = i + 1; j < n; j++){if (a[i] > a[j]){a[i] ^= a[j];a[j] ^= a[i];a[i] ^= a[j];}}}}

简单选择排序

复杂度O(n^2),性能略优于冒泡,交换操作少

void SimpleSort(vector<int> &a){int n = a.size(),min;for (int i = 0; i < n; i++){min = i;for (int j = i+1; j < n; j++){if (a[min] > a[j])min = j;}if (i!=min){a[i] ^= a[min];a[min] ^= a[i];a[i] ^= a[min];}}}

直接插入排序

复杂度O(n^2),性能优于冒泡和简单选择排序

思想跟理手上的扑克牌一样,将每一个数插入到已经排好序的记录中

void InsertionSort(vector<int> &a){int n = a.size(),j,temp;for (int i = 1; i < n; i++){if (a[i] < a[i - 1]){temp = a[i];j = i;while (j > 0 && a[j-1]>temp){a[j] = a[j-1];j--;}a[j] = temp;}}}


快速排序

复杂度O(nlogn)

int helper(vector<int> &a, int low, int high){int i = low, j = high, x = a[low];while (i < j){while (i < j&&a[j] > x)j--;if (i < j)a[i++] = a[j];while (i < j&&a[i] < x)i++;if (i < j)a[j--] = a[i];}a[i] = x;return i;}void sort(vector<int> &a, int low, int high){if (low < high){int i=helper(a, low, high);sort(a, low, i - 1);sort(a, i + 1, high);}}void QuickSort(vector<int> &a){sort(a, 0, a.size() - 1);}
修改sort方法减少递归次数

void sort(vector<int> &a, int low, int high){while (low < high){int i=helper(a, low, high);sort(a, low, i - 1);low = i + 1;}}





归并排序

复杂度O(nlogn),但因为用了递归,所以比较占内存,但是效率高且稳定

void merge(vector<int> &a, int low, int mid, int high){int i = low, j = mid + 1, n = high - low + 1, k = 0;vector<int> v(n);while (i <= mid&&j <= high)v[k++] = a[i] < a[j] ? a[i++] : a[j++];while (i <= mid)v[k++] = a[i++];while (j <= high)v[k++] = a[j++];for (i = low; i <= high; i++)a[i] = v[i - low];}void sort(vector<int> &a, int low, int high){if (low < high){int mid = low + (high - low) / 2;sort(a, low, mid);sort(a, mid + 1, high);merge(a, low, mid, high);}}void MergeSort(vector<int> &a){sort(a, 0, a.size() - 1);}

非递归版本

思路是先两两归并(0 1)(2 3)(4 5)...然后再每四个归并(0 1 2 3)(4 5 6 7),即间隔k=1 2 4...个归并

其中merge子函数和递归版本一样

void merge(vector<int> &a, int low, int mid, int high){int i = low, j = mid + 1, n = high - low + 1, k = 0;vector<int> v(n);while (i <= mid&&j <= high)v[k++] = a[i] < a[j] ? a[i++] : a[j++];while (i <= mid)v[k++] = a[i++];while (j <= high)v[k++] = a[j++];for (i = low; i <= high; i++)a[i] = v[i - low];}void MergeSort(vector<int> &a){int n = a.size(),low,mid,high,k=1;while (k < n){low = 0;while (low + k < n){mid = low + k - 1;high = mid + k > n - 1 ? n - 1 : mid + k;merge(a, low, mid, high);low = high + 1;}k *= 2;}}



0 0