算法训练之快速排序

文章详细介绍了快速排序算法,包括其时间复杂度、排序思路、算法图解和具体实现。通过两道编程题展示了快速排序的应用,一道是排序数组,另一道是找出数组中第k小的整数。同时,提供了C++代码示例来解释算法的执行过程。
摘要由CSDN通过智能技术生成


这里附上我老婆的照片,每天激励我学习
ALT

学习内容的原始链接

主要学习内容是来自浙江大学的数据结构的学习,感兴趣的可以自己去看一下哦~

算法简单介绍以及解析

我们今天学习的算法是快速排序

其时间复杂度是 o ( n l o g n ) o(nlogn) o(nlogn)的调整序列中元素的位置,对于序列中元素的指标并没有统一的规定,一般以 A [ 1 ] A[1] A[1]作为基准进行排序,使得 A [ 1 ] A[1] A[1]左侧所有元素不超过 A [ 1 ] A[1] A[1],右侧所有元素大于 A [ 1 ] A[1] A[1]

快速排序的思路

① 调整序列中的元素,使得当前序列最左端的元素调整后满足左侧所有元素均不超过该元素,右侧所有元素均大于该元素
②对该元素的左右两侧分别进行递归 ①的调整,直到当前调整区间的长度不超过1

算法图解

在一个乱序的数组当中找到一个值放入到temp当中,让后使用 l e f t left left r i g h t right right两个指针进行分析
在这里插入图片描述
在这里插入图片描述

算法的总体思路

  1. 先将 A [ 1 ] A[1] A[1]存至某一个临时变量temp,并令下标left,right分别指向序列的首位
  2. 只要right指向的元素 A [ r i g h t ] A[right] A[right]大于temp,就将right左移(right++),当某个时候 A [ r i g h t ] ≤ t e m p A[right]\le temp A[right]temp 时,将元素 A [ r i g h t ] A[right] A[right]挪到left指向的元素 A [ l e f t ] A[left] A[left]
  3. 只要left指向的元素 A [ l e f t ] A[left] A[left]不超过temp,就将left右移(left–),当某个时候 A [ l e f t ] ≥ t e m p A[left] \ge temp A[left]temp 时,将元素 A [ l e f t ] A[left] A[left]挪到right指向的元素 A [ r i g h t ] A[right] A[right]
  4. 重复第二,三步直到两个指针leftright相遇,把temp当存储的值放到两个指针相遇的地方

快速排序算法题

【模板】快速排序

题目描述

利用快速排序算法将读入的 N N N 个数从小到大排序后输出。

快速排序是信息学竞赛的必备算法之一。对于快速排序不是很了解的同学可以自行上网查询相关资料,掌握后独立完成。(C++ 选手请不要试图使用 STL,虽然你可以使用 sort 一遍过,但是你并没有掌握快速排序算法的精髓。)

输入格式

1 1 1 行为一个正整数 N N N,第 2 2 2 行包含 N N N 个空格隔开的正整数 a i a_i ai,为你需要进行排序的数,数据保证了 a i a_i ai 不超过 1 0 9 10^9 109

输出格式

将给定的 N N N 个数从小到大输出,数之间空格隔开,行末换行且无空格。

样例 #1

样例输入 #1
5
4 2 4 5 1
样例输出 #1
1 2 4 4 5

提示

对于 20 % 20\% 20% 的数据,有 N ≤ 1 0 3 N\leq 10^3 N103

对于 100 % 100\% 100% 的数据,有 N ≤ 1 0 5 N\leq 10^5 N105

题解

#include<iostream>
using namespace std;

const int N=100010;
int q[N];
int n;
void quick_sort(int q[],int l,int r)
{
    if(l>=r)return ;
    int i=l-1,j=r+1,x=q[(l+r)>>1];
    while(i<j)
    {
    do i++;while(q[i]<x);
    do j--;while(q[j]>x);
    if(i<j)swap(q[i],q[j]);
    }
    quick_sort(q,l,j);
    quick_sort(q,j+1,r);
}
int main()
{
    scanf("%d",&n);
    for(int i=0;i<n;++i)scanf("%d",&q[i]);
    quick_sort(q,0,n-1);
    for(int i=0;i<n;++i)printf("%d ",q[i]);
    return 0;
}

2.第 k 小整数

题目描述

现有 n n n 个正整数,要求出这 n n n 个正整数中的第 k k k 个最小整数(相同大小的整数只计算一次)。

输入格式

第一行为 n n n k k k; 第二行开始为 n n n 个正整数的值,整数间用空格隔开。

输出格式

k k k个最小整数的值;若无解,则输出 NO RESULT

样例 #1

样例输入 #1
10 3
1 3 3 7 2 5 1 2 4 6
样例输出 #1
3

提示

n ≤ 10000 n \leq 10000 n10000 k ≤ 1000 k \leq 1000 k1000,正整数均小于 30000 30000 30000

解析

#include<iostream>
using namespace std;
const int N=100010;
int q[N];
int n,k,y;
void del(int q[])//删除重复数值
{
    for(int i=1;i<=n;++i)
    {
        for(int j=i+1;j<=n;++j)
        {
            if(q[i]==q[j])
            {
                for(int y=j;y<n;++y)
                {
                    q[y]=q[y+1];
                }
                n--;
                j--;
            }
        }
    }
}
void quick_sort(int q[],int l,int r)
{   
    if(l>=r)return ;
    int i=l-1,j=r+1,x=q[(l+r)>>1];
    while(i<j)
    {
    do i++;while(q[i]<x);
    do j--;while(q[j]>x);
    if(i<j)swap(q[i],q[j]);
    }
    quick_sort(q,l,j);
    quick_sort(q,j+1,r);
}
int main()
{
    scanf("%d %d",&n,&k);
    for(int i=1;i<=n;++i)scanf("%d",&q[i]);
    del(q);
    quick_sort(q,1,n);
    //for(int i=1;i<=n;++i)
    if(n>=k)printf("%d",q[k]);
    else printf("NO RESULT");
    return 0;
}

学习新得体会

今天的学习内容是什么呢?就是我们的今日份学习内容[根据需要进行修改]

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值