常用的七大排序
十大排序
https://zhuanlan.zhihu.com/p/172524701
冒泡排序
- 解释:
相邻的两个值把最大的值放在右边,最小值放在左边,一次循环确定最后一个位置,逐层递进 - 代码
//十大排序之冒泡排序 //升序 void bubble(vector<int>& ans) { if(ans.empty() || ans.size() == 1) { return; } int size = ans.size(); int change; for(int i = 1; i < size; i++) { for(int j = 1; j <= size - i; j++) { if(ans[j - 1] > ans[j]) { change = ans[j - 1]; ans[j - 1] = ans[j]; ans[j] = change; } } } }
选择排序
- 解释:
从第一个位置寻找之后位置的最小值,将其和第一个值换位,然后逐层递进 - 代码
//十大排序之选择排序 //升序 void SelectSorte(vector<int>& ans) { int size = ans.size(); int change; for(int i = 0; i < size; i++) { pair<int, int> m(i,ans[i]); for(int j = i; j < size; j++) { if(ans[j] < m.second) { m.first = j; m.second = ans[j]; } } change = ans[m.first]; ans[m.first] = ans[i]; ans[i] = change; } }
插入排序
- 解释:
位置i开始(i之前都是按照升序排好的),将位置i的数在0-i之间找一个位置放下它, - 代码
//十大排序之插入排序 //升序 void InsertSorte(vector<int>& ans) { int size = ans.size(); int change; for(int i = 0; i < size; i++) { // for(int j = i; j >= 1 ; j--) { // if(ans[j - 1] > ans[j]) { // change = ans[j - 1]; // ans[j - 1] = ans[j]; // ans[j] = change; // } // } for(int j = i; j >= 1 && ans[j - 1] > ans[j]; j--) { change = ans[j - 1]; ans[j - 1] = ans[j]; ans[j] = change; } } }
希尔排序
-
解释:
希尔排序是一种改善的插入排序,每次取间隔gap的大小分为一组,在组内进行插入排序,最后gap一定是等于1,那么就是间隔1进行插入排序有,就是一般的插入排序了
它的时间复杂度首次突破O(n2),平均的是O(n1.3),但是最坏的情况还是O(n^2) -
代码
int shellSorte(vector<int>& ans) { int flag = 0; int change; int size = ans.size(); int gap = size/2; while (gap >= 1) { for(int i = gap; i < size; i++) { for(int j = i; j >= gap && ans[j - gap] > ans[j]; j -= gap) { change = ans[j - gap]; ans[j - gap] = ans[j]; ans[j] = change; flag++; } } gap = gap/2; } return flag; } -
和一般的插入比较:(分别比较一般的插入排序和希尔排序循环次数对比)
输入数据是vector<int> ans1 = {22,8,9,1,7,2,3,5,4,6,0,23,10}; vector<int> ans2 = {22,8,9,1,7,2,3,5,4,6,0,23,10};
归并排序
-
解释:
我们已知排序两个已知的有序数组的方法是使用双指针,我们怎么把一个数组分成有序的数组呢,就是一步一步分下来分成单个元素,那不就是有序的吗,之后再治之(也就是排序) -
代码
int flag; void MergeSort(vector<int>& ans, int begin, int end) { if(begin >= end) { return; } //我们需要做的是分而治之,以下的递归做的是分 int mid = (begin + end) >> 1; MergeSort(ans, begin, mid); MergeSort(ans, mid + 1, end); //至此,分的操作已经完成,要开始的是治(也就是排序) int begin1 = begin, end1 = mid, begin2 = mid + 1, end2 = end; //将两个数组的数据进行合并 vector<int> temp; while(begin1 <= end1 && begin2 <= end2) { temp.push_back(ans[begin1] > ans[begin2] ? ans[begin2++] : ans[begin1++]); } while(begin1 <= end1) { temp.push_back(ans[begin1++]); } while(begin2 <= end2) { temp.push_back(ans[begin2++]); } cout << "第" << flag++ << "次合并" << endl; for(int i = begin; i <= end; i++) { ans[i] = temp[i - begin]; cout << ans[i] << " "; } cout << endl; cout << "************************************" << endl; } -
分治的过程
我们需要排序的数组是vector<int> ans = {8,9,1,7,2,3,5,4,6};
快速排序
- 解释:
选择一个位置作为标杆,之后用双指针得到以标杆为中心的一个数组,标杆之前为小于标杆的数,标杆之后为大于标杆的数,之后递归往下 - 代码
//十大排序之快速排序 //升序 void quickSort(vector<int>& arr, int start, int end) { if (start >= end) { return; } int flag = arr[end];//选取最后一位作为标杆 int left = start, right = end - 1; //使用双指针来实现从大到小的排序(最好用草稿本写以下就知道了) while (left < right) { //注意以下循环的顺序,先进行的是left,之后才是right,所以最后在确定flag的位置的时候很重要 while (arr[left] < flag && left < right) left++; // ^ while (arr[right] >= flag && left < right) right--; // | std::swap(arr[left], arr[right]); // | } // | if (arr[left] >= arr[end]) // | std::swap(arr[left], arr[end]); // | else // | left++; //left的位置为什么要++,因为 --------------------- quickSort(arr, start, left - 1); quickSort(arr, left + 1, end); }
堆排序
- 解释:
首先第一步是先建立一个大顶堆(或者小顶堆),之后通过交换首尾的位置,下沉尾部的目的达到排序的目的 - 代码
//十大排序之堆排序
//大顶堆
//维护堆的性质,用于建立大顶堆
void heapidf(vector<int>& ans, int size, int i) {
int parent = i;
int lson = 2*i + 1;
int rson = 2*i + 2;
if(lson < size && ans[parent] < ans[lson]) {
parent = lson;
}
if(rson < size && ans[parent] < ans[rson]) {
parent = rson;
}
//说明此时需要交换
if(parent != i) {
swap<int>(ans[parent], ans[i]);
heapidf(ans, size, parent);
}
}
//排序入口
void heapsort(vector<int>& ans) {
int size = ans.size();
for(int i = size-1; i >= 0; i--) {
heapidf(ans, size,i);
}
//到此处为止已经建立好了大顶堆了,之后要进行堆排序
//原来的 ans = {6, 6, 8, 9, 9, 1, 7, 2, 3, 5, 4};
//现在的 ans = {9, 9, 8, 6, 6, 1, 7, 2, 3, 5, 4};
for(int i = size - 1; i >= 0; i--) {
//排序的步骤为,先交换首尾的位置
swap<int>(ans[i], ans[0]);
//之后将尾部(此时的尾部到了首部的位置)沉下去
heapidf(ans, i, 0);
}
}

浙公网安备 33010602011771号