算法学习---快速排序和归并排序.

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言AcWing算法学习第一节
  • 一、排序
    • 1.快速排序
    • 2.归并排序
  • 总结:这些模板一定要理解着学习,但是先理解尽力去理解,然后给这个模板背下来,然后你才可以在比赛的时候给他用最少的时间做出来,所以必须特别熟练


前言

请大家带着认真读这篇文章,因为这是梦想开始的地方


提示:以下是本篇文章正文内容,下面案例可供参考

一、快速排序

示例:让一些数字以从大到小或从小到大排序的一种方法.

1.输入和输出

代码如下(示例):

//基础输入输出
#include<stdio.h>
int main()
{
    int arr[100010];
    int n,k;
    scanf("%d %d",&n,&k);
    for(int i=0;i<n;i++) scanf("%d",&arr[i]);
    
    quick_sort(arr,0,n-1);
    
    for(int i=0;i<n;i++) 
    {
        if(i+1==k) printf("%d",arr[i]);
    }
    return 0;
}

2.函数书写

代码如下(示例):

void quick_sort(int arr[],int l,int r)
{
    if(l>=r) return;  //特殊情况特殊讨论
    int i=l-1,j=r+1,x=arr[l]; //第一点 指针思想,i是初始指针,j是末尾指针然后通过左右遍历去
    //实现交换,指针配合reverse逆序其实这种思想很常见,只能说见怪不怪吧。
    //第二点就是x=arr[l]就是以这个值为边界,去左边排比他大的或小的 右边排比他小或大的.
    while(i<j)
    {
        do i++;while(arr[i]<x);
        do j--;while(arr[j]>x);
        if(i<j)
        {
            int tmp=arr[i];
            arr[i]=arr[j];
            arr[j]=tmp;
        }
    }
    quick_sort(arr,l,j);  //递归实现左边可以顺序
    quick_sort(arr,j+1,r);//递归实现右边可以顺序
}

3.总代码的默写

#include<stdio.h>
void quick_sort(int arr[],int l,int r)
{
    if(l>=r) return;
    int i=l-1,j=r+1,x=arr[l];
    while(i<j)
    {
        do i++;while(arr[i]<x);
        do j--;while(arr[j]>x);
        if(i<j)
        {
            int tmp=arr[i];
            arr[i]=arr[j];
            arr[j]=tmp;
        }
    }
    quick_sort(arr,l,j);
    quick_sort(arr,j+1,r);
}
int main()
{
    int arr[100010];
    int n,k;
    scanf("%d %d",&n,&k);
    for(int i=0;i<n;i++) scanf("%d",&arr[i]);
    
    quick_sort(arr,0,n-1);
    
    for(int i=0;i<n;i++) 
    {
        if(i+1==k) printf("%d",arr[i]);
    }
    return 0;
}
//我再强调一遍,一定要把模板会背,并且练到纯熟.

二、归并排序

1.输入和输出

#include<stdio.h>
const int N=100010;
int arr[N],tmp[N];
void merge_sprt(int arr[],int l,int r)
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++) scanf("%d",&arr[i]);
    merge_sprt(arr,0,n-1);
    for(int i=0;i<n;i++) printf("%d ",arr[i]);
    return 0;
}

2.函数书写

void merge_sprt(int arr[],int l,int r)
{
    if(l>=r) return;

    int mid=(l+r)/2;//归并思想其实就是分治二分,所以用到了mid
    merge_sprt(arr,l,mid),merge_sprt(arr,mid+1,r);//把大于这个的放到一边,不大于的放到另一边

    int i=l,j=mid+1,k=0;
    while(i<=mid&&j<=r)//这里tmp[]类似于book[]数组名作用就是装入到里面而已.
    {
        if(arr[i]<=arr[j]) tmp[k++]=arr[i++];
        else tmp[k++]=arr[j++];
    }
    while(i<=mid) tmp[k++]=arr[i++];
    while(j<=r) tmp[k++]=arr[j++];

    for(int i=l,j=0;i<=r;i++,j++) arr[i]=tmp[j];//当然装了还要物归原主的,方便打印的.

}

3.总代码的默写

#include<stdio.h>
const int N=100010;
int arr[N],tmp[N];

void merge_sprt(int arr[],int l,int r)
{
    if(l>=r) return;

    int mid=(l+r)/2;
    merge_sprt(arr,l,mid),merge_sprt(arr,mid+1,r);

    int i=l,j=mid+1,k=0;
    while(i<=mid&&j<=r)
    {
        if(arr[i]<=arr[j]) tmp[k++]=arr[i++];
        else tmp[k++]=arr[j++];
    }
    while(i<=mid) tmp[k++]=arr[i++];
    while(j<=r) tmp[k++]=arr[j++];

    for(int i=l,j=0;i<=r;i++,j++) arr[i]=tmp[j];

}
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++) scanf("%d",&arr[i]);
    merge_sprt(arr,0,n-1);
    for(int i=0;i<n;i++) printf("%d ",arr[i]);
    return 0;
}

练习题目:、


题意理解
这道题目显然是要我们将一个无序数列排序,成为具有升序性质的升序序列.

算法处理
一道排序题目,数据范围是关键,我们发现这道题目只能让我们使用O(nlogn)O(nlogn)的算法,显然我们可以选择快速排序,归并排序等算法,这里我们就使用快速排序

#include<stdio.h>
int arr[100010];

void quick_sort(int arr[],int l,int r)
{
    if(l>=r) return;
    int i=l-1,j=l+1,x=arr[l];
    while(i<j)
    {
        do i++;while(arr[i]>x);
        do j--;while(arr[j]<x);
        if(i<j)
        {
            int tmp=arr[i];
            arr[i]=arr[j];
            arr[j]=tmp;
        }
    }
    quick_sort(arr,l,j);
    quick_sort(arr,j+1,r);
    
}

int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++) scanf("%d",&arr[i]);
    
    quick_sort(arr,0,n-1);
    
    for(int i=0;i<n;i++) printf("%d ",arr[i]);
    
    return 0;
}

#include<stdio.h>
void quick_sort(int arr[],int l,int r)
{
    if(l>=r) return;
    int i=l-1,j=r+1,x=arr[l];
    while(i<j)
    {
        do i++;while(arr[i]<x);
        do j--;while(arr[j]>x);
        if(i<j)
        {
            int tmp=arr[i];
            arr[i]=arr[j];
            arr[j]=tmp;
        }
    }
    quick_sort(arr,l,j);
    quick_sort(arr,j+1,r);
}
int main()
{
    int arr[100010];
    int n,k;
    scanf("%d %d",&n,&k);
    for(int i=0;i<n;i++) scanf("%d",&arr[i]);

    quick_sort(arr,0,n-1);

    for(int i=0;i<n;i++) 
    {
        if(i+1==k) printf("%d",arr[i]);
    }
    return 0;
}

题意理解
题意很清晰,就是让我们使用快速排序算法,求解第K小的数.

算法选择
快速排序算法,显然是我们不二选择.毕竟这是一道模板题目

题意理解
这道题目还是让我们排序,只不过这里强制要求我们使用归并排序,所以既然如此的话,让我们好好地康康这道题目.

算法处理
归并排序,它有两大核心操作.

一个是将数组一分为二,一个无序的数组成为两个数组.

另外一个操作就是,合二为一,将两个有序数组合并成为一个有序数组.

#include<stdio.h>
const int N=100010;
int arr[N],tmp[N];

void merge_sprt(int arr[],int l,int r)
{
    if(l>=r) return;
    
    int mid=(l+r)/2;
    merge_sprt(arr,l,mid),merge_sprt(arr,mid+1,r);
    
    int i=l,j=mid+1,k=0;
    while(i<=mid&&j<=r)
    {
        if(arr[i]<=arr[j]) tmp[k++]=arr[i++];
        else tmp[k++]=arr[j++];
    }
    while(i<=mid) tmp[k++]=arr[i++];
    while(j<=r) tmp[k++]=arr[j++];
    
    for(int i=l,j=0;i<=r;i++,j++) arr[i]=tmp[j];
    
}
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++) scanf("%d",&arr[i]);
    merge_sprt(arr,0,n-1);
    for(int i=0;i<n;i++) printf("%d ",arr[i]);
    return 0;
}

总结

1.模板固然重要但是不要忘了初心是为了学习,是为了自己变得更强,而不是为了竞赛获奖,竞赛只是编程的一部分不是全部,有这样的心态才能走好这条路,否则你会虚荣,攀比,慢慢迷失自己,加油吧,少年!

2.思考什么是卷?什么是细?(下期回答)

  • 20
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 19
    评论
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夏目浅石.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值