排序(左神初级)p1

1.冒泡排序(有序O(N),最差O(N^2),平均O(N^2) ,稳定)

基本思想:外层循环控制次数,内层是两两比较,把每一轮未排定部分最大的元素放到了数组的末尾。

                                                Bubble-sort.gif

 vector<int> sortArray(vector<int>& nums) {
       for(int i = 1;i < nums.size(); i++) {//i表示趟数,共n-1趟
            bool swaped = false;
            for(int j = 0; j < nums.size() - i; j++) {//每趟减少1个。
                if(nums[j] > nums[j+1]) {//相等不交换,所以稳定
                    swap(nums[j+1], nums[j]);
                    swaped = true;
                }
            }
            if(!swaped)return nums; 
        }
        return nums;
    }

2.选择排序(最好O(N)已有序, 最坏O(N^2),平均O(N^2) ,稳定)

还是两层for循环,第一层控制移动第i个位置,第二层选择当前最小的数放置到该位置。通俗的说,就是第一次选最小的元素与num[0]交换,第二次从num[1]开始选择最小元素与num[1]交换……

                                         selection-sort.gif

 vector<int> sortArray(vector<int>& nums) {
    //共选择n-1次
      for(int i=0;i<nums.size()-1;i++){
          //先令min为当前位置元素
          int min=i;
         //每一次都选择到最后一个元素
         for(int j=i+1;j<nums.size();j++){
           //选择最小的元素
              min=nums[min]<nums[j]?min:j;
             }
          //交换
           swap(nums[i],nums[min]);  
      }
      return nums;
    }

3.插入排序

两层for循环,第一层控制当前元素,第二层确定该元素要被插入到已经排序好的哪个位置。

                                       insertion-sort.gif

    vector<int> sortArray(vector<int>& nums) {
       for(int i=1;i<nums.size();i++){//默认[0]位置已经排序好,从后一个位置开始
          //该元素的前一个位置[j]-开始位置[0]已经排序好
           for(int j=i-1;j>=0 && nums[j]>nums[j+1];j--){
               swap(nums[j],nums[j+1]);
           }
       }
     return nums;
    }

4.归并排序(O(nlogn),)

分治的思想,一分为二,先让左边右边都排序,再new一个新的辅助数组,两个指针分别指向左右两边的第一个元素,谁小就放置哪个元素。

                                                                     merge-sort.gif

class Solution {
public:
    vector<int> temp;
    vector<int> sortArray(vector<int>& nums) {
        temp = vector<int>(nums.size(), 0);
        mergesort(0, nums.size() - 1,nums);
        return nums;

    }
    void mergesort(int l,int r,vector<int>& nums){
      if (l >= r) return;
       int mid=(l+r)/2;
       //左右都排序
       mergesort(l,mid,nums);
       mergesort(mid+1,r,nums);
       
       int i=0;
       int p1=l;  //p1p2两个指针
       int p2=mid+1;
        
       while(p1<=mid && p2<=r){
          //将小的元素放入辅助数组
          temp[i++]=nums[p1]<=nums[p2]?nums[p1++]:nums[p2++];
       }
       //没有越过边界的剩余元素
       while(p1<=mid )temp[i++]=nums[p1++];
       while(p2<=r )temp[i++]=nums[p2++];
       //拷贝入原数组      
       for (i = 0; i < r - l + 1; ++i) nums[l + i] = temp[i];

    }
};

归并的扩展:

逆序对:

实际是归并的过程,只需在排序的途中记录下逆序的个数。

class Solution {
public:
    int res=0;
    vector<int> temp;
    int reversePairs(vector<int>& nums) {
    temp = vector<int>(nums.size(), 0);
        return mergesort(0, nums.size() - 1,nums);

    }
    int mergesort(int l,int r,vector<int>& nums){
      if (l >= r) return 0;
       int mid=(l+r)/2;
       
       mergesort(l,mid,nums);
       mergesort(mid+1,r,nums);

       int i=0;
       int p1=l;
       int p2=mid+1;
       //int* temp = new int[right-left+1]; 
       while(p1<=mid && p2<=r){
           if(nums[p1]>nums[p2]){
          temp[i++]=nums[p2++];
           res+=mid-p1+1;
       }else{
        temp[i++]=nums[p1++];
        }
       }
       while(p1<=mid )temp[i++]=nums[p1++];
       while(p2<=r )temp[i++]=nums[p2++];
      
       for (i = 0; i < r - l + 1; ++i) nums[l + i] = temp[i];
       return res;
       
    }
};

小和问题:(代码暂时还有点问题)

在一个数组中,每一个数左边比当前数小的数累加起来,叫做这个数组的小和。

{1,3,4,2,5}
1左边比1小的数,没有
3左边比3小的数,1;
4左边比4小的数,1、3;
2左边比2小的数,1;
5左边比5小的数,1、3、4、2;
所以小和为1+1+3+1+1+3+4+2=16

#include<iostream>
#include <vector>
#include <windows.h>

using namespace std;
int merge1(vector<int>num,int l,int r);
vector<int> temp;
int cont=0;


int merge1(vector<int>num,int l,int r){
  if(l>=r)return 0;

  int mid=(l+r)/2;

  merge1(num,l,mid);
  merge1(num,mid+1,r);

  int i=0,p1=l,p2=mid+1;
  while(p1<=mid && p2<=r){
    if(num[p1]<num[p2]){
        temp[i++]=num[p1];
        cont+=(r-p2+1)*num[p1];
        p1++;
    }else{
       temp[i++]=num[p2++];
    }
  }
    while(p2<=r)temp[i++]=num[p2++];
    while(p1<=mid)temp[i++]=num[p1++];

  for(auto c:temp)num[i+l]=temp[i];
  return cont;

}



int main(){
  int n;
  cin>>n;
  int a;
  temp=vector<int>(n);
  vector<int> num;
  for (int i=0;i<n;i++){
    cin>>a;
    num.push_back(a);
  }

  merge1(num,0,n-1);
  cout<<cont<<endl;

system("pause");
}


 

Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值