算法基础-排序题

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

交换式排序-快速排序

快速排序是一种不稳定排序方法,在元素移动过程中产生了逆序。排序算法的稳定性即,排序前2个相等的数其在序列的前后位置顺序和排序后它们两个的前后位置顺序相同。
快速排序用到了递归函数,其时间复杂度为o(nlogn)
其代码如下:

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 将给定数组排序
     * @param arr int整型vector 待排序的数组
     * @return int整型vector
     */
    //快速排序
    int Partition(vector<int>& arr,int low,int high){
        int i,j;
        i=low,j=high;
        int tmp=arr[i];
        do{
            while(arr[j]>=tmp&&i<j){
                j--; //j向左扫描,直到遇见比arr[0]更小的
            }
            arr[i]=arr[j];
            while(arr[i]<=tmp&&i<j){
                i++; //i向右扫描,直到遇见比arr[0]更大的
            }
            arr[j]=arr[i]; //交换ij
        }while(i!=j);
        arr[i]=tmp;
        return i;
    }
    void quickSort(vector<int>& arr,int low,int high) {
        int i;
        if(low<high){
            i=Partition(arr,low,high);
            quickSort(arr, low, i-1);
            quickSort(arr, i+1, high);
        }
            
    }
    void mySort1(vector<int>& arr) {
        quickSort(arr, 0, arr.size()-1);
    } 

    vector<int> MySort(vector<int>& arr) {
        // write code here
        mySort1(arr);
        return arr;
    }
    
    
};

选择式排序-堆排序

选择式排序的基本思想是:
每一趟从待排序的记录中选出关键字最小或最大的记录,按顺序放在记录序列的最后或最前。

我目前学到的选择式排序(简单选择排序和堆排序)都是不稳定排序,其空间复杂度为o(1),时间复杂度为o(nlogn)

一般的解决方案

其代码如下(成功ac):
    
    //-----堆排序-----
    void Sift(vector<int>& arr,int i,int n){
        int left = 2*i + 1; // index的左子节点
        int right = 2*i + 2;// index的右子节点
 
        int maxIdx = i;
        if(left<n && arr[left] > arr[maxIdx])maxIdx = left;
        if(right<n && arr[right] > arr[maxIdx])maxIdx = right;
 
        if(maxIdx != i)
        {
            swap(arr[maxIdx], arr[i]);
            Sift(arr, maxIdx, n);
        }
    }
    
    void heapSort(vector<int>& arr){
        int i;
        int n=arr.size();
        //把所有的非叶结点都筛选一遍
        for(int i=n/2-1;i>=0;i--){
            Sift(arr,i,n); //建立初始最大堆
        }
        for(int i=n-1;i>=1;i--){ //做n-1趟堆排序
            swap(arr[0],arr[i]);
            Sift(arr,0,i);
        }
    }
    
    
};

遇到的问题

下面一个用循环写的sift函数,思路好像也没毛病,但不知道为什么堆排序的正确率只有80%…修改sift函数为上面的递归以后才能够正确运行:
如果有大神看出来哪里有问题可否指点一下我这个菜TAT。

    //-----堆排序-----
    void Sift(vector<int>& arr,int i,int n){
        int j;
        j=i*2+1; //j是i的左儿子
        while(j<=n){
            if(j<n&&arr[j]<arr[j+1]){
               j++; //j是i的右儿子
            }

            if(j<n&&arr[j]>arr[i]){
               swap(arr[i], arr[j]);
               i=j; //继续检查下一个儿子
               j=i*2+1;
            }else break;
        }
    }

利用STL priority_queue解决

参考链接:
http://c.biancheng.net/view/480.html
在这里插入图片描述
priority_queue 实例默认有一个 vector 容器。函数对象类型 less 是一个默认的排序断言,定义在头文件 function 中,决定了容器中最大的元素会排在队列前面。function 中定义了 greater,用来作为模板的最后一个参数对元素排序,最小元素会排在队列前面。当然,如果指定模板的最后一个参数,就必须提供另外的两个模板类型参数。

    //-----堆排序-----
    void heapSort(vector<int>& arr){
        priority_queue<int,vector<int>,greater<int>> q;
        for(int i=0;i<arr.size();i++){
            q.push(arr[i]);
        }
        
        for(int i=0;i<arr.size();i++){
            arr[i]=q.top();
            q.pop();
        }
    }

用这种方法似乎速度会比之前一般的自己写堆排序快一些:
在这里插入图片描述

归并排序

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值