数组题——排序数组

排序数组

题目描述

给定一个整数数组 nums,将该数组升序排列。

解题思路

冒泡排序法:从头到尾对每一个数都进行算法运算,要循环(nums.end())次,每次都从开始将相邻两个元素对比,大的交换到下面(已经对比过最大的必须要再进行对比)因此总共对比(nums.end()-(已经对比过的数字数量a-nums.begin())-1)次。使用swap(a,b)函数来进行交换处理。

注意:因为对比是用*b与*(b+1)进行对比的,因此在对比循环中(内循环)是要注意结束条件,不能指向空地址end(),要-1。

class Solution {
public:
    vector<int> sortArray(vector<int>& nums) 
    {
        for(auto a=nums.begin();a<nums.end();a++)
            for(auto b=nums.begin();b<(nums.end()-(a-nums.begin())-1);b++)
                if(*b>*(b+1)) swap(*b,*(b+1));
        return nums;
    }
};

但是冒泡超出了时间限制。

快速排序法:找开始的数作为基准值,内轮循环是先从右往左遍历找到比基准值小的数,将其与基准值(l所在对应)交换,然后再从左往右遍历找到比基准数大的数,将其与基准值(当前r所对应位置)交换。外循环是将整个数组以基准值为中心分成左右两部分。

class Solution {
public:
    vector<int> sortArray(vector<int>& nums) 
    {
      my_sort(nums,nums.begin(),nums.end()-1);//特别注意这里的end()-1
      return nums;
    }
    void my_sort(vector<int>& nums,auto left,auto right)
    {
      if(left<right)
      {
        auto l=left,r=right;
        int jizhun=*left;
        while(l<r)
        {
          while(l<r&&*r>=jizhun) r--;
          if(l<r) *l++=*r;//*l++等价于*(l++),虽然是先运算l++,但是指针引用返回的是l初始值,所以没问题。
          while(l<r&&*l<jizhun) l++;//<
          if(l<r) *r--=*l;
        }
        *l=jizhun;//大循环外,给当前l也就是基准值应该在的位置赋值
/*      while(l<r)
        {
          while(l<r&&*r>=jizhun) r--;//右找小,如果大就继续找
          if(l<r) swap(*l++,*r);//*l++等价于*(l++),虽然是先运算l++,但是指针引用返回的是l初始值,所以没问题。
          while(l<r&&*l<jizhun) l++;//左找大,如果小就继续找,<=也可以
          if(l<r) swap(*r--,*l);
        }
*/
        my_sort(nums,left,l-1);//这里用到递归,根据基准值分成左右两个区间,再分别再左右两个区间找
        my_sort(nums,l+1,right);//l为基准值的位置,left,right为当前两个区间边界
      }
    }
};
  1. 这里使用递归的思想来进行快速排序。
  2. 这里可以不用swap()函数,而是直接将要交换的值赋值过来,我们可以发现最后l的位置就是基准值的位置,只需要将最终的l位置赋值以初始值即可。
  3. 我觉得我没搞懂快速,还不会编,需要多看看 多想想。

归并排序法:使用递归的思想。分治。分:先将数组一直二分成两部分,直到每一部分都只有一个元素。治:将左右两部分,从开始到结尾一一进行对比,总共对比(left.size()+right.size()),将小的push_back进新的容器中。

  1. 递归先写递归终止条件:if(nums.size()==1);
  2. 二分法递归:b=nums.begin(),e=nums.end() ;left=my_sort(vector<int> (b,b+(e-b)/2)),right=——(b+(e-b)/2,e)
  3. 然后建立新容器,左右部分从头到尾开始比较,总共比较left.size()+right.size()次:l=left.begin(),r=right.begin();
  4. 小的先放入容器:判定条件分为可以放左(在左边没到end()的情况下,要么右边没了【end()】||要么左边比右边小),放右的条件(在右边没到end()的情况下,要么左边没了【end()】||要么右边比左边小):l!=left.end()&&(r==right.end()||*l<*r),r!=right.end()&&(l==left.end()||*l>=*r)
  5. 当前部分排序好了之后,返回当前容器值
class Solution {
public:
    vector<int> sortArray(vector<int>& nums) {
        return my_sort(nums);
    }
    vector<int> my_sort(vector<int> nums){
        //if(nums.size()==0) return{};
        if(nums.size()==1) return nums;
        auto b=nums.begin(),e=nums.end();
        vector<int> left = my_sort(vector<int> (b,b+(e-b)/2));
        vector<int> right = my_sort(vector<int> (b+(e-b)/2,e));
        auto l=left.begin(),r=right.begin();
        vector<int> ans;
        for(int i=0;i<(left.size()+right.size());i++)
        {
            if (l != left.end()&&(r ==right.end()||*l<*r)){ 
            
                ans.push_back(*l);
                l++;
                continue;
            }
            if (r != right.end()&&(l ==left.end()||*l>=*r)){
                ans.push_back(*r);
                r++;
                continue;
            }              
        }
        return ans;
    }
};

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值