各种排序及内省排序

来源:互联网 发布:摄影后期知乎 编辑:程序博客网 时间:2024/06/05 23:59

分别写了选择、冒泡、插入、堆、归并、快排的实现,以及基于快排的内省排序,并于STL的排序相比较。

//algo.h#pragma onceint min(int x, int y){return x < y ? x : y;}int max(int x, int y){return x > y ? x : y;}void swap(int& x, int& y){int temp = x;x = y;y = temp;}

//sort.h#pragma once#include<vector>#include"algo.h"void insertsort(std::vector<int> &vec){int m = vec.size();for (int i = 1; i < m; i++){int temp = vec[i];int j = i - 1;while (j >= 0 && temp < vec[j]){vec[j + 1] = vec[j];j--;}vec[j+1] = temp;}}void maopao(std::vector<int> &vec){int m = vec.size();for (int i = 0; i < m; i++){for (int j = 0; j < m - i - 1; j++){if (vec[j] > vec[j + 1])swap(vec[j], vec[j + 1]);}}}void xuanze(std::vector<int> &vec){int m = vec.size();for (int i = 0; i < m; i++){int index = i;for (int j = i; j < m; j++){if (vec[j] < vec[index]){index = j;}}swap(vec[i], vec[index]);}}

//heapsort.h#pragma once#include<vector>#include"algo.h"void up(std::vector<int>& vec, int i){int par = (i - 1) / 2;while (par && vec[i]<vec[par]){swap(vec[i], vec[par]);i = par;par = (i - 1) / 2;}}void down(std::vector<int> &vec, int i, int end){int child = i * 2 + 1;while (child < end){if (child + 1 < end && vec[child] < vec[child + 1])child++;if (vec[i] < vec[child])swap(vec[i], vec[child]);elsebreak;i = child;child = i * 2 + 1;}}void heapsort(std::vector<int>& vec){int m = vec.size();for (int i = m/2-1; i>=0; i--){down(vec, i, m);}for (int i = m-1; i>0; i--){swap(vec[0], vec[i]);down(vec, 0, i);}}

//mergesort.h#pragma once#include<vector>#include"algo.h"void merge(std::vector<int> &vec, int left_beg, int right_beg, int right_end, std::vector<int> &fuzhu){int left_end = right_beg - 1;int i = left_beg, j = right_beg;int index = left_beg;while (i <= left_end && j <= right_end){if (vec[i] < vec[j])fuzhu[index++] = vec[i++];elsefuzhu[index++] = vec[j++];}while (i <= left_end)fuzhu[index++] = vec[i++];while (j <= right_end)fuzhu[index++] = vec[j++];for (int beg = left_beg; beg <= right_end; beg++)vec[beg] = fuzhu[beg];}void mergesort_recusive(std::vector<int> &vec, int beg, int end, std::vector<int> &fuzhu){if (beg < end){int mid = beg + (end - beg) / 2;mergesort_recusive(vec, beg, mid, fuzhu);mergesort_recusive(vec, mid + 1, end, fuzhu);merge(vec, beg, mid+1, end, fuzhu);}}void mergesort(std::vector<int> &vec){int m = vec.size();std::vector<int> fuzhu(m, 0);mergesort_recusive(vec, 0, m - 1, fuzhu);}

//qsort.h#pragma once#include<vector>#include"algo.h"void mid_of_three_swap(std::vector<int>& vec, int beg, int end)//头中尾三个取中间值与尾元素交换{int mid = beg + (end - beg) / 2;int mid_index;if (vec[beg] > vec[mid]){if (vec[mid] > vec[end]){swap(vec[mid], vec[end]);return;}else{if (vec[beg] < vec[end]) swap(vec[beg], vec[end]);return;}}else{if (vec[beg] > vec[end]){swap(vec[beg], vec[end]);return;}else{if (vec[mid] < vec[end]) swap(vec[mid], vec[end]);return;}}}int partition_Lomuto(std::vector<int> &vec, int beg, int end)//单向,加上一点优化{int key = vec[end];while (vec[beg] < key)//可以避免已经排好的情况{if (++beg == end) return beg;}int next = beg + 1;for (; next < end; next++){if (vec[next] < key){swap(vec[next], vec[beg++]);}}swap(vec[beg], vec[end]);return beg;}int partition_Lomuto2(std::vector<int> &vec, int beg, int end)//单向,无优化{int key = vec[end];for (int next = beg; next < end; next++){if (vec[next] < key){swap(vec[next], vec[beg++]);}}swap(vec[beg], vec[end]);return beg;}int partition_Hoare(std::vector<int> &vec, int beg, int end)//双向{int key = vec[end];while (beg<end){while (beg < end && vec[beg] <= key) beg++;vec[end] = vec[beg];while (beg<end && vec[end] >= key)  end--;vec[beg] = vec[end];}vec[end] = key;return end;}void qsort_recusive(std::vector<int> &vec, int beg, int end){if (beg < end){mid_of_three_swap(vec, beg, end);int index = partition_Hoare(vec, beg, end);qsort_recusive(vec, beg, index - 1);qsort_recusive(vec, index + 1, end);}}void qsort(std::vector<int> &vec){qsort_recusive(vec, 0, vec.size() - 1);}

//mysort.h#pragma once#include<vector>#include"algo.h"void _mid_of_three_swap(std::vector<int>& vec, int beg, int end){int mid = beg + (end - beg) / 2;int mid_index;if (vec[beg] > vec[mid]){if (vec[mid] > vec[end]){swap(vec[mid], vec[end]);return;}else{if (vec[beg] < vec[end]) swap(vec[beg], vec[end]);return;}}else{if (vec[beg] > vec[end]){swap(vec[beg], vec[end]);return;}else{if (vec[mid] < vec[end]) swap(vec[mid], vec[end]);return;}}}int _lg(int n){int ret = 0;while (n>1){ret++;n = n >> 1;}return ret;}int _partition_Hoare(std::vector<int> &vec, int beg, int end){int key = vec[end];while (beg<end){while (beg < end && vec[beg] <= key) beg++;vec[end] = vec[beg];while (beg<end && vec[end] >= key)  end--;vec[beg] = vec[end];}vec[end] = key;return end;}void _insert(std::vector<int> &vec, int beg, int end){for (int i = beg+1; i <= end; i++){int temp = vec[i];int j = i - 1;while (j >= beg && temp < vec[j]){vec[j + 1] = vec[j];j--;}vec[j + 1] = temp;}}void _down(std::vector<int> &vec, int i, int end){int child = i * 2 + 1;while (child < end){if (child + 1 < end && vec[child] < vec[child + 1])child++;if (vec[i] < vec[child])swap(vec[i], vec[child]);elsebreak;i = child;child = i * 2 + 1;}}void _heapsort(std::vector<int>& vec, int beg, int end){int m = end-beg+1;for (int i = beg + m / 2 - 1; i >= beg; i--){_down(vec, i, m);}for (int i = beg + m - 1; i>beg; i--){swap(vec[beg], vec[i]);_down(vec, beg, i);}}void _qsort_recusive(std::vector<int> &vec, int beg, int end, int depth_limit){if (--depth_limit == 0){_heapsort(vec, beg, end);return;}if (end-beg>16){_mid_of_three_swap(vec, beg, end);int index = _partition_Hoare(vec, beg, end);_qsort_recusive(vec, beg, index - 1, depth_limit);_qsort_recusive(vec, index + 1, end, depth_limit);}else{_insert(vec, beg, end);}}void mysort(std::vector<int> &vec){int m = vec.size();_qsort_recusive(vec, 0, m - 1, 2*_lg(m));}

//main.h#include<vector>#include<iostream>#include<ctime>#include<algorithm>#include"qsort.h"#include"heapsort.h"#include"sort.h"#include"mergesort.h"#include"mysort.h"using namespace std;void show(vector<int> &vec){for (auto x : vec){cout << x << " ";}cout << endl;}void test(){srand(time(0));vector<int> vec(10000000, 0);for (int i = 0; i < 10000000; i++){vec[i] += rand() % 10000000;}vector<int> vec0(vec);vector<int> vec1(vec);vector<int> vec2(vec);vector<int> vec3(vec);vector<int> vec4(vec);vector<int> vec5(vec);vector<int> vec6(vec);cout << "数据量 " << vec.size() << endl;clock_t a, b;a = clock();sort(vec.begin(), vec.end());b = clock();cout << "stl " << b - a << endl;a = clock();mysort(vec0);b = clock();cout << "我的 " << b - a << endl;//show(vec0);a = clock();qsort(vec1);b = clock();cout << "快排 " << b - a << endl;a = clock();mergesort(vec2);b = clock();cout << "归并 " << b - a << endl;a = clock();heapsort(vec3);b = clock();cout << "堆 " << b - a << endl;a = clock();xuanze(vec4);b = clock();cout << "选择 " << b - a << endl;a = clock();maopao(vec5);b = clock();cout << "冒泡 " << b - a << endl;a = clock();insertsort(vec6);b = clock();cout << "插入 " << b - a << endl;}void main(){test();char c; cin >> c;}

单位:ms



内省快排,一方面限制了递归的深度适时采取堆排序,另一方面当范围元素个数少时(16以下)采用插入排序。

只是在快排上做了一些微小的工作,性能上相较快排提升了不少,与stl里的sort性能也接近了不少。

stl的sort分析见:http://www.udpwork.com/item/12284.html