基础排序
冒泡排序
for(int i=0;i<arr.size()-1;i++)
for(int j=0;j<arr.size()-1-i;j++)
if(arr[j]>arr[j+1])
swap(arr[j],arr[j+1]);
选择性排序
for(int i=0;i<arr.size();i++){
int minIndex=i;
for(int j=i+1;j<arr.size();j++)
if(arr[minIndex]>arr[j])
minIndex=j;
swap(arr[i],arr[minIndex]);
}
插入排序
for(int i=1;i<arr.size()-1;i++)
for(int j=i;j>0;j--)
if(arr[j-1]>arr[j])
swap(arr[j],arr[j-1]);
else
break;
高级排序
归并排序
#include <iostream>
#include <algorithm>
#include <ctime>
#include <stdlib.h>
using namespace std;
//* VS不支持动态长度数组, 即不能使用 T aux[r-l+1]的方式申请aux的空间
//* 使用VS的同学, 请使用new的方式申请aux空间
//* 使用new申请空间, 不要忘了在__merge函数的最后, delete掉申请的空间:)
template<typename T>
void merge(T arr[], int l, int mid, int r){
T *aux=new T[r-l+1];
for(int i=l; i<r+1; i++)
aux[i-l]=arr[i];
int li=l;
int ri=mid+1;
for (int j=l; j<r+1; j++){
if(li>mid) {
arr[j]=aux[ri-l];
ri++;
}
else if(ri>r){
arr[j]=aux[li-l];
li++;
}
else if(aux[li-l]>aux[ri-l]){
arr[j]=aux[ri-l];
ri++;
}else{
arr[j]=aux[li-l];
li++;
}
}
delete[] aux;
}
template<typename T>
void _mergeSort(T arr[], int l, int r){
if(l>=r) return;
int mid=l+(r-l)/2;
_mergeSort(arr, l, mid);
_mergeSort(arr, mid+1, r);
if(arr[mid]>arr[mid+1])
merge(arr, l, mid, r);
}
template<typename T>
void mergeSort(T arr[], int n){
if(n<2) return;
_mergeSort(arr, 0, n-1);
}
int main() {
// 测试1 一般性测试
cout<<"Test for random array, size = "<<10<<", random range [0, "<<10<<"]"<<endl;
int arr2[10] ={1,2,6,4,3,2,5,9,3,7};
mergeSort( arr2, 10);
for(int i=0;i<10;i++)
cout<<arr2[i]<<' ';
cout<<endl;
system("pause");
return 0;
}
快速排序
#include <iostream>
#include <algorithm>
#include <ctime>
#include <stdlib.h>
using namespace std;
template <typename T>
int part(T arr[],int l, int r){
int v=rand()%(r-l+1)+l;
swap(arr[l], arr[v]);
int i=l+1;
int j=r;
while(i<=j){
if(arr[i]<arr[l])
i++;
else if(arr[j]>arr[l])
j--;
else{
swap(arr[i],arr[j]);
i++;
j--;
}
}
swap(arr[j],arr[l]);
return j;
}
template <typename T>
void _quickSort(T arr[],int l, int r){
if( r<= l ){
return;
}
int t=part(arr, l, r);
_quickSort(arr, l, t);
_quickSort(arr, t+1, r);
}
template<typename T>
void quickSort(T arr[], int n){
if(n<2) return;
_quickSort(arr, 0, n-1);
}
int main() {
// 测试1 一般性测试
cout<<"Test for random array, size = "<<10<<", random range [0, "<<10<<"]"<<endl;
int arr2[10] ={1,2,6,4,3,2,5,9,3,7};
quickSort( arr2, 10);
for(int i=0;i<10;i++)
cout<<arr2[i]<<' ';
cout<<endl;
system("pause");
return 0;
}
#include <iostream>
#include <algorithm>
#include <ctime>
#include <stdlib.h>
using namespace std;
template<typename T>
int part3(T arr[],int l, int r){
int v=rand()%(r-l+1)+l;
swap(arr[l], arr[v]);
int i=l+1, j=r,cur=l+1;
while(cur<=j){
if(arr[cur]<arr[l]){
swap(arr[cur],arr[i]);
i++;
cur++;
}
else if(arr[cur]>arr[l]){
swap(arr[cur],arr[j]);
j--;
}else
cur++;
}
swap(arr[i-1],arr[l]);
return i-1;
}
template<typename T>
void _quickSort(T arr[],int l, int r){
if( r<= l ){
return;
}
int t=part3(arr, l, r);
_quickSort(arr, l, t);
_quickSort(arr, t+1, r);
}
template<typename T>
void quickSort(T arr[], int n){
if(n<2) return;
_quickSort(arr, 0, n-1);
}
int main() {
// 测试1 一般性测试
cout<<"Test for random array, size = "<<10<<", random range [0, "<<10<<"]"<<endl;
int arr2[10] ={1,2,6,4,3,2,5,9,3,7};
quickSort( arr2, 10);
for(int i=0;i<10;i++)
cout<<arr2[i]<<' ';
cout<<endl;
system("pause");
return 0;
}
堆排序
堆:
- 完全二叉树;
- 堆中节点的值总是不大于(或不小于)其父节点的值。
堆排序:
- 交换堆顶元素和最后一个元素;
- 自顶向下重建堆;
- 重复步骤1。
- 升序——最大堆
- 降序——最小堆
#include <iostream>
#include <algorithm>
#include <ctime>
#include <stdlib.h>
#include "SortTestHelper.h"
using namespace std;
template<typename T>
void ajustDown(T arr[], int n,int root){
int left=2*root+1;
int right=2*root+2;
if(left>=n) return;
int maxIndex;
if(right<n&&arr[right]>arr[left])
maxIndex=right;
else
maxIndex=left;
if(arr[root]>arr[maxIndex]) return;
swap(arr[root],arr[maxIndex]);
ajustDown(arr,n,maxIndex);
}
template<typename T>
void createHeap(T arr[], int n){
for(int i=(n-1-1)/2;i>=0;i--){
ajustDown(arr,n,i);
}
}
template<typename T>
void heapSort(T arr[], int n){
if(n<2) return;
createHeap(arr,n);
for(int i=0;i<n;i++){
swap(arr[0],arr[n-1-i]);
ajustDown(arr,n-1-i,0);
}
}
int main() {
// 测试1 一般性测试
cout<<"Test for random array, size = "<<10<<", random range [0, "<<10<<"]"<<endl;
int arr2[10] ={1,2,6,4,3,2,5,9,3,7};
heapSort( arr2, 10);
for(int i=0;i<10;i++)
cout<<arr2[i]<<' ';
cout<<endl;
system("pause");
return 0;
}
排序复杂度分析
排序算法 | 时间复杂度 | 原地排序 | 空间复杂度 | 稳定排序 |
---|---|---|---|---|
插入排序 | O(n²) | 是 | O(1) | 是 |
归并排序 | O(nlogn) | 否 | O(n) | 是 |
快速排序 | O(nlogn) | 是 | O(1) | 否 |
堆排序 | O(nlogn) | 是 | O(1) | 否 |
衍生问题
快速排序
力扣215:数组中找到第 k 个最大的元素
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
int r=nums.size()-1;
int n;
n=maxK(nums,0,r,k);
return n;
}
private:
int quikS(vector<int>& nums, int l,int r){
int rd=rand()%(r-l+1)+l;
int v=nums[rd];
swap(nums[l],nums[rd]);
int l1,r1,cur;
l1=l+1;
r1=r;
cur=l+1;
while(cur<=r1){
if(nums[cur]>v)
swap(nums[l1++],nums[cur++]);
else if(nums[cur]<v)
swap(nums[r1--],nums[cur]);
else cur++;
}
swap(nums[l],nums[l1-1]);
return l1-1;
}
int maxK(vector<int>& nums, int l,int r,int k){
int q;
q=quikS(nums,l,r);
if(q+1<k)
return maxK(nums,q+1,r,k);
else if(q+1>k)
return maxK(nums,l,q-1,k);
else return nums[q];
return -1;
}
};
利用归并排序求逆序对
剑指offer51
#include <iostream>
#include <algorithm>
#include <ctime>
#include <stdlib.h>
using namespace std;
//* VS不支持动态长度数组, 即不能使用 T aux[r-l+1]的方式申请aux的空间
//* 使用VS的同学, 请使用new的方式申请aux空间
//* 使用new申请空间, 不要忘了在__merge函数的最后, delete掉申请的空间:)
int globalCount=0;
template<typename T>
void merge(T arr[], int l, int mid, int r){
T *aux=new T[r-l+1];
for(int i=l; i<r+1; i++)
aux[i-l]=arr[i];
int li=l;
int ri=mid+1;
for (int j=l; j<r+1; j++){
if(li>mid) {
arr[j]=aux[ri-l];
ri++;
}
else if(ri>r){
arr[j]=aux[li-l];
li++;
}
else if(aux[li-l]>aux[ri-l]){
globalCount+=mid-li+1;//在归并排序的基础上加了一句,求逆序对
arr[j]=aux[ri-l];
ri++;
}else{
arr[j]=aux[li-l];
li++;
}
}
delete[] aux;
}
template<typename T>
void _mergeSort(T arr[], int l, int r){
if(l>=r) return;
int mid=l+(r-l)/2;
_mergeSort(arr, l, mid);
_mergeSort(arr, mid+1, r);
if(arr[mid]>arr[mid+1])
merge(arr, l, mid, r);
}
template<typename T>
int mergeSort(T arr[], int n){
if(n<2) return 0;
_mergeSort(arr, 0, n-1);
return globalCount;
}
int main() {
int arr2[10] ={7,5,6,4};
int n=4;
// 测试1 一般性测试
cout<<"Test for random array, size = "<<n<<", random range [0, "<<n<<"]"<<endl;
int c;
c= mergeSort( arr2, n);
for(int i=0;i<n;i++)
cout<<arr2[i]<<' ';
cout<<endl;
cout<<"逆序对:"<<c<<endl;
system("pause");
return 0;
}