|
平均时间复杂度 |
最好情况 |
最坏情况 |
空间复杂度 |
排序方式 |
稳定性 |
选择排序 |
O(n^2) |
O(n^2) |
O(n^2) |
O(1) |
in-place |
不稳定 |
冒泡排序 |
O(n^2) |
O(n) |
O(n^2) |
O(1) |
in-place |
稳定 |
插入排序 |
O(n^2) |
O(n) |
O(n^2) |
O(1) |
in-place |
稳定 |
归并排序 |
O(n logn) |
O(n logn) |
O(n logn) |
O(n) |
out-place |
稳定 |
快速排序 |
O(n logn) |
O(n logn) |
O(n^2) |
O(logn) |
in-place |
不稳定 |
希尔排序 |
O(n logn) |
O(n log^2n) |
O(n log^2n) |
O(1) |
in-place |
不稳定 |
堆排序 |
O(n logn) |
O(n logn) |
O(n logn) |
O(1) |
in-place |
不稳定 |
计数排序 |
O(n+k) |
O(n+k) |
O(n+k) |
O(k) |
out-place |
稳定 |
桶排序 |
O(n+k) |
O(n+k) |
O(n^2) |
O(n+k) |
out-place |
稳定 |
基数排序 |
O(kn) |
O(kn) |
O(kn) |
O(n+k) |
out-place |
稳定 |
选择排序
vector<int> selectionSort(vector<int> nums){
for(int i=0;i<nums.size();i++){
int left_min_pos = i;
for(int j=i+1;j<nums.size();j++)
if(nums[j]<nums[left_min_pos]) left_min_pos = j;
//swap
int temp = nums[left_min_pos];
nums[left_min_pos] = nums[i];
nums[i] = temp;
}
return nums;
}
冒泡排序
vector<int> bubbleSort(vector<int> nums){
for(int i=nums.size()-2;i>=0;i--){
for(int j=0;j<=i;j++){
if(nums[j]>nums[j+1]){
int temp = nums[j];
nums[j] = nums[j+1];
nums[j+1] = temp;
}
}
}
return nums;
}
插入排序
vector<int> insertionSort(vector<int> nums){
for(int i=1;i<nums.size();i++){
for(int i=1;i<nums.size();i++){
int value = nums[i];
int j=i;
while(j>0&&nums[j-1]>value){
nums[j]=nums[j-1];
j--;
}
nums[j]=value;
}
return nums;
}
归并排序
void merge(vector<int> &nums,int p,int r){
int q = (p+r)/2;
//cout<<q<<endl;
vector<int> l1(q-p,0),l2(r-q,0);
for(int i=0;i<l1.size();i++)
l1[i] = nums[p+i];
for(int i=0;i<l2.size();i++)
l2[i] = nums[q+i];
int p1,p2;p1=p2=0;
for(int i=p;i<r;i++){
if(p1==l1.size()){
for(int j=i;j<r;j++)
nums[j]=l2[p2++];
break;
}
if(p2==l2.size()){
for(int j=i;j<r;j++)
nums[j]=l1[p1++];
break;
}
if(l1[p1]<=l2[p2]) nums[i]=l1[p1++];
else nums[i]=l2[p2++];
}
}
void mergeSort(vector<int> &nums,int p,int r){
//cout<<p<<":"<<r<<endl;
if(p+1>=r) //!!!边界问题
return;
mergeSort(nums,p,(p+r)/2);
mergeSort(nums,(p+r)/2,r);
merge(nums,p,r);
}
快速排序
void quickSort(vector<int> &nums,int p,int r){
if(p+1>=r) return;
int pivot = (p+r)/2;
int temp = nums[p];nums[p]=nums[pivot];nums[pivot]=temp; //pivot 在列首
int value = nums[p];
pivot=p;
for(int i=p+1;i<r;i++){
if(nums[i]<value){
pivot++;
if(pivot!=i)
{int temp = nums[i];nums[i]=nums[pivot];nums[pivot]=temp;}
}
}
nums[p] = nums[pivot];
nums[pivot]=value;
quickSort(nums,p,pivot);
quickSort(nums,pivot,r);
}
希尔排序
vector<int> shellSort(vector<int> nums){
for(int delta = nums.size()/2;delta>=1;delta/=2){
for(int i=delta;i<nums.size();i++){
int value = nums[i];
int j=i;
while(j>=delta&&nums[j-delta]>value){
nums[j] = nums[j-delta];
j-=delta;
}
nums[j] = value;
}
}
return nums;
}
堆排序
- l = 2p+1 r = 2p+2;
- p = (l-1)/2 p = (r-1)/2
- 最大堆
void buildHeap(vector<int> &nums){
for(int i=1;i<nums.size();i++){
int p;
while((p=(i-1)/2)>=0&&nums[p]<nums[i]){
int temp = nums[p];
nums[p] = nums[i];
nums[i] = temp;
i = p;
}
}
}
vector<int> heapSort(vector<int> nums){
buildHeap(nums); //插入法,也可用筛选法:从第一个非叶子结点向下筛选,直到根元素筛选完毕
for(int i=nums.size()-1;i>0;i--){
int newParent = nums[i];nums[i]=nums[0];nums[0]=newParent;
int leftChild,p=0;
while((leftChild = 2*p+1)<i){
if(leftChild+1<i&&nums[leftChild]<nums[leftChild+1]&&nums[p]<nums[leftChild+1])
{
int temp = nums[p];nums[p]=nums[leftChild+1];nums[leftChild+1]=temp;
p=leftChild+1;
}
else if(nums[p]<nums[leftChild])
{
int temp = nums[p];nums[p]=nums[leftChild];nums[leftChild]=temp;
p=leftChild;
}
else
break;
}
}
return nums;
}
计数排序
vector<int> countingSort(vector<int> &nums){
vector<int> coun(k+1,0); //range: 0~k, (k+1)个,找出max, min
for(auto num:nums) //C
coun[num]++;
for(int i=1;i<coun.size();i++) //C
coun[i] +=coun[i-1];
vector<int> ans(nums.size(),0);
for(int i=nums.size()-1;i>=0;i--){ //B!!从后到前,为了稳定:22 42 23
ans[--coun[nums[i]]]=nums[i];
}
return ans;
}
桶排序
vector<int> bucketSort(vector<int> &nums){
vector<int> buckets[4];
for(auto num:nums){ //分桶
buckets[num/3].push_back(num);
}
// for(auto bucket:buckets) 不可
// insertionSort(bucket);
for(int i=0;i<4;i++){ //桶排序
insertionSort(buckets[i]);
for(auto bucket:buckets[i])
cout<<bucket<<" ";
cout<<endl;
}
vector<int> results;
for(auto bucket:buckets){ //合并桶
for(auto item:bucket)
results.push_back(item);
}
return results;
}
基数排序
vector<int> radixSort(vector<int> &nums){
for(int r=1;nums[0]/r!=0;r*=10){ //r位数
vector<int> coun(10,0); //里面是计数排序
vector<int> b;
for(auto num:nums){
b.push_back(num);
coun[(num/r)%10]++;
}
for(int i=1;i<coun.size();i++){
coun[i]+=coun[i-1];
}
for(int i=nums.size()-1;i>=0;i--){
nums[--coun[(b[i]/r)%10]]=b[i];
}
}
return nums;
}