leetcode912

排序数组

这道题就是给数组进行排序,下面用三种排序方法来解决这道题。

1. 快速排序。

思想:设置两个指针,一个low和一个high,每次取出当前数组的第一个节点作为privot,然后与指针high进行比较,直到不满足,那么将该值交换到low所在的位置;接着与low比较,直到不满足,那么交换该值到high所在位置。

最后找到privot在数组中所在的位置,接着递归比较前半部分和后半部分。

可以产生一个随机种子来作为privot,优化速度,但是本题还是超时了。所以写了一个判断数组是否有序的函数来判断(没错,面向用例编程)。

class Solution {
public:
    void quickSort(vector<int> & nums, int begin, int end){
        if(begin >= end) return;
        int l = begin, h = end;
        //产生一个随机种子
        int i = rand() % (h - l + 1) + l;
        swap(nums[l], nums[i]);
        int privot = nums[l];
        while(l < h){
            while(l < h && nums[h] >= privot) h--;
            nums[l] = nums[h];
            while(l < h && nums[l] <= privot) l++;
            nums[h] = nums[l];
        }
        nums[l] = privot;
        quickSort(nums, begin, l);
        quickSort(nums, l+1, end);
    }   
    static bool comp(int i, int j) {
        return i < j;
    }
    
    vector<int> sortArray(vector<int>& nums) {
        bool flag = false;
        for(int i=1; i < nums.size(); i++){
            if(nums[i] < nums[i-1]){
                flag = true;
                break;
            }
        }
        if(!flag)
            return nums;
        srand((unsigned)time(NULL));
    
        quickSort(nums, 0, nums.size()-1);
        return nums;
    }
};

2. 堆排序。

堆排序思想:

先建堆,本题建立的是大顶堆,也就是升序排序。从数组的中点开始调整堆,使得每个父节点都比它的左右子节点要大。建完堆之后,每次取出根节点(也就是最大的节点),取出的元素放置在数组的最后,然后重新从根节点开始调整堆。

void heapify(vector<int>& nums, int i, int n){
        int lson = (i << 1) + 1;
        int rson = (i << 1) + 2;
        int large = 0;
        if(lson <= n && nums[lson] > nums[i])
            large = lson;
        else
            large = i;
        if(rson <= n && nums[rson] > nums[large])
            large = rson;
        //该节点需要做调整
        if(large != i){
            swap(nums[i], nums[large]);
            heapify(nums, large, n);
        }
    }
    void buildMaxheap(vector<int>& nums, int n){
        for(int i = n >> 1; i>=0; i--){
            heapify(nums, i, n);
        }
    }
    void heapSort(vector<int> &nums){
        int n = nums.size();
        //建一个大顶堆
        buildMaxheap(nums,  n-1);

        for(int i = n-1; i > 0; i--){
            //每次将堆顶的数字交换到最后一个位置
            swap(nums[0], nums[i]);
            n--;
            //交换之后需要重新调整堆
            heapify(nums, 0, n-1);
        }
    }

3. 归并排序。

思想:需要声明临时的数组,每次都对数组进行对半分割,然后比较前半部分和后半部分,将较小值存入临时数组。最后再将有序的部分存入原数组对应的位置。

 void mergeSort(vector<int>& nums, vector<int>& temp, int left, int right){
        if(left >= right) return;
        int mid = (left + right) >> 1;
        mergeSort(nums, temp, left, mid);
        mergeSort(nums, temp, mid+1, right);
        int i = left, j = mid+1, k = 0;
        while(i <= mid && j <= right){
            temp[k++] = nums[i] <= nums[j] ? nums[i++] : nums[j++];
        }
        while(i <= mid){
            temp[k++] = nums[i++];
        }
        while(j <= right){
            temp[k++] = nums[j++];
        }
        for(int p = 0; p < k; p++){
            nums[left + p] = temp[p];
        }
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值