zoukankan      html  css  js  c++  java
  • 【算法·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;
    }
    
    from Chu
  • 相关阅读:
    cron表达式详解
    C# Quartz 调度任务辅助类
    SQLserver查询用逗号隔开的字段中是否包含另一个字段的值
    c# 将字符串转换为逻辑表达式(字符串转换布尔)
    铺砖块
    字符串涂漆
    快餐店
    乘号加号
    传纸条(lgP1006)
    小明的喷漆计划
  • 原文地址:https://www.cnblogs.com/chubuyu/p/15119551.html
Copyright © 2011-2022 走看看