排序总结


在这里插入图片描述
在这里插入图片描述

基于比较操作

交换排序

冒泡排序
class Solution {
public:
    vector<int> sortArray(vector<int>& nums) {
        int n=nums.size();
        bool isChange;
        int i,j;
        for(i=0;i<n-1;i++){
            //n-1趟
            isChange=false;//这趟是否有交换
            for(j=0;j<n-i-1;j++){
                if(nums[j]>nums[j+1]){
                    swap(nums[j],nums[j+1]);
                    isChange=true;
                }
            }
            if(isChange==false)
                break;
        }
        return nums;
    }
};
快速排序
class Solution {
public:
    int partition(int low,int high,vector<int>& nums){
        int tem=nums[low];
        while(low<high){
            while(low<high&&nums[high]>=tem)
                high--;
            nums[low]=nums[high];
            while(low<high&&nums[low]<=tem)
                low++;
            nums[high]=nums[low];
        }
        nums[low]=tem;
        return low;
    }
    void Quick_sort(int low,int high,vector<int>& nums){
        if(low<high){
            int pos=partition(low,high,nums);
            Quick_sort(low,pos-1,nums);
            Quick_sort(pos+1,high,nums);
        }

    }
    vector<int> sortArray(vector<int>& nums) {
        Quick_sort(0,nums.size()-1,nums);
        return nums;
    }
};

插入排序

直接插入排序
class Solution {
public:
    vector<int> sortArray(vector<int>& nums) {
        int i,j;
        int len=nums.size();
        int tem;
        for(i=1;i<len;i++){
            tem=nums[i];
            j=i-1;
            while(j>=0&&nums[j]>tem)
                {
                    nums[j+1]=nums[j];
                    j--;
                }
            nums[j+1]=tem;
        }
    return nums;
    }
};
希尔排序
/*
Shell_sort
不稳定 分组插入可能使后面的跃居到前面
平均:O(n^1.3)
最好:O(n)
最坏:O(n^2)
空间:O(1)
*/
class Solution {
public:
    vector<int> sortArray(vector<int>& nums) {
        int i,j;
        int tem;
        int len=nums.size();
        int gap=len/2;
        while(gap!=0){
            for(i=gap;i<len;i++){
                tem=nums[i];
                j=i-gap;
                while(j>=0&&nums[j]>tem){
                    nums[j+gap]=nums[j];
                    j-=gap;
                }
                nums[j+gap]=tem;
            }
            gap/=2;
        }
        return nums;
    }
};

选择排序

简单选择排序
/*
Selection_sort
不稳定,选出的最小元素与元素i交换的时候可能把i交换到后面去了 
平均:O(n^2)
最好:O(n^2)
最坏:O(n^2)
空间:O(1)
*/
class Solution {
public:
    vector<int> sortArray(vector<int>& nums) {
        int i,j;
        int n=nums.size();
        int minid;
        for(i=0;i<n-1;i++){
            minid=i;
            for(j=i+1;j<n;j++){
                if(nums[j]<nums[minid])
                    minid=j;
            }
            if(minid!=i)
                swap(nums[minid],nums[i]);
        }
    return nums;
    }
};
堆排序
/*
Heap_sort
不稳定,把父结点换下去的时候,有可能会把它换到靠后的位置
平均:O(nlgn)
最好:O(nlgn)
最坏:O(nlgn)
空间:O(1)
*/
class Solution {
public:
    void heapfy(vector<int>& nums,int i,int n){
        
        int left=i*2;
        int right=left+1;
        int maxid=i;
        if(left<n&&nums[left]>nums[maxid])
            maxid=left;
        if(right<n&&nums[right]>nums[maxid])
            maxid=right;
        if(maxid!=i){
            swap(nums[maxid],nums[i]);
            heapfy(nums,maxid,n);
        }

    }
    void Max_heap(vector<int>& nums,int n){
        int i;
        for(i=n/2;i>=0;i--)
            heapfy(nums,i,n);

    }
    vector<int> sortArray(vector<int>& nums) {
        int i;
        int n=nums.size();
        int len=n;
        Max_heap(nums,n);
        for(i=0;i<n-1;i++){
            swap(nums[0],nums[n-i-1]);
            len--;
            heapfy(nums,0,len);
        }
        return nums;
    }
};

归并排序

普通归并排序
/*
Merge_sort
稳定
平均:O(nlgn)
最好:O(nlgn)
最坏:O(nlgn)
空间:O(n)
*/
class Solution {
public:
    void Merge_sort(vector<int>& nums,vector<int>& b,int left,int right){
        if(left>=right)
            return;
        int mid=(left+right)/2;
        Merge_sort(b,nums,left,mid);
        Merge_sort(b,nums,mid+1,right);
        int i,j,k;
        for(i=left,j=mid+1,k=left;i<=mid&&j<=right;){
            if(b[i]<=b[j])
                nums[k++]=b[i++];
            else nums[k++]=b[j++];
        }
        while(i<=mid&&k<=right)
            nums[k++]=b[i++];
        while(j<=right&&k<=right)
            nums[k++]=b[j++];
    }
    vector<int> sortArray(vector<int>& nums) {
        int i;
        int n=nums.size();
        vector<int> b=nums;
        Merge_sort(nums,b,0,n-1);

        return nums;
    }
};

建堆时间复杂度O(n), 调整一次O(lgn),调整n次O(nlgn)

基于比较排序的算法复杂度理论下界

相当于找出叶子个数为n!(排序可能的个数)的最佳决策树

复杂度=树高= O(log(n!))

非比较排序

计数排序

统计得到数组的最小值min,最大值max,申请一个长度为max-min+1的数组。建立一个数组b,b[i]存储A数组中值<=i的数字数量,计算出每个数字应该在原数组中的位置放回去。

class Solution
{
public:
    int* coutSort(int* data, int length)
    {
        if (data == nullptr || length <= 0)
            return nullptr;

        //确定数列最大值
        int max = data[0];
        int min = data[0];
        for (int i = 1; i < length; ++i)
        {
            if (data[i] > max)
                max = data[i];
            if (data[i] < min)
                min = data[i];
        }
        int d = max - min;
        // 确定统计数组长度并进行初始化
        int* coutData = new int[d + 1];
        for (int i = 0; i <= d; ++i)
            coutData[i] = 0;
        // 遍历数组,统计每个数出现的次数
        for (int i = 0; i < length; ++i)
                ++coutData[data[i] - min];
        // 统计数组做变形,后面的元素等于前面的元素之和
        for (int i = 1; i <= d; ++i)
            coutData[i] += coutData[i - 1];
    // 倒序遍历原始数列,从统计数组找到正确的位置,输出到结果数组
        int* sortedArray = new int[length];
        for (int i = length - 1; i >= 0; i--)
        {
            sortedArray[coutData[data[i] - min] - 1] = data[i];        // 找到data[i]对应的coutData的值,值为多少,表示原来排序多少,(因为从1开始,所以再减1)
            coutData[data[i] - min]--;        // 然后将相应的coutData的值减1,表示下次再遇到此值时,原来的排序是多少。
        }
        return sortedArray;
    }
};

算法稳定性详解

参考资料

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值