【算法·Algorithms】 Sort

平均时间复杂度 最好情况 最坏情况 空间复杂度 排序方式 稳定性
选择排序 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;
}
posted @ 2021-08-09 17:07  楚不予  阅读(36)  评论(0编辑  收藏  举报