从0开始学算法--排序(1.7快速排序)

算法理解:

  对于无序数组里的任意一个数字V,总有一部分数字小于V,一部分数字大于V。如果我们将比V小的数字放在V的前面,比V大的数字放在后面,那V所在的位置就是整个数组排序后V应该在的位置。

  同时我们得到了两个连续的无序数组,和归并排序一样左右递归处理即可。

#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#include <cstdio>
#include <cmath>
#include <queue>

using namespace std;

const int maxn=1e5+10;
int num[maxn];

void quicksort(int left,int right){
    int temp,t,i,j;
    if(left>=right)return;
    temp=num[left];
    i=left;
    j=right;
    while(i<j){
        while(num[j]>temp&&i<j){
            j--;
        }
        while(num[i]<=temp&&i<j){
            i++;
        }
        if(i<j){
            t=num[j];
            num[j]=num[i];
            num[i]=t;
        }
    }
    num[left]=num[i];
    num[i]=temp;
    quicksort(left,i-1);
    quicksort(i+1,right);
    return;
}

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

例一:求数组第k小元素

#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#include <cstdio>
#include <cmath>
#include <queue>

using namespace std;

const int maxn=1e5+10;
//分治思想,如果当前值使第6小,那么求第3小时只用查找前6个元素,而不用找后面的元素
void quickselect(int a[],int l,int r,int rank){
    int i=l,j=r,mid=a[(l+r)/2];
    do{
        while(a[i]<mid)++i;
        while(a[j]>mid)--j;
        if(i<=j){
            swap(a[i],a[j]);
            ++i,--j;
        }
    }while(i<=j);
    if(l<=j&&rank<=j-l+1)quickselect(a,l,j,rank);
    if(i<=r&&rank>=i-l+1)quickselect(a,i,r,rank-(i-l));
}

int quick_select(int a[],int n,int k){
    quickselect(a,1,n,k);
    return a[k];
}

int main(){
    int a[maxn];
    int n,k;
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    printf("%d\n",quick_select(a,n,k));
    return 0;
}

原文地址:https://www.cnblogs.com/wz-archer/p/11689372.html

时间: 2024-11-09 02:52:59

从0开始学算法--排序(1.7快速排序)的相关文章

从0开始学算法--排序(1.12c++利用标准库排序)

1,简单数组按升序排序 sort(a,a+n); #include <algorithm> #include <iostream> #include <cstring> #include <vector> #include <cstdio> #include <cmath> #include <queue> using namespace std; const int maxn=1e5+10; int a[maxn]; i

从0开始学算法--排序(1.5归并排序)

算法理解: 一个数组长度为n,他的前m个元素是升序的,后n-m个元素升序的,怎么使整个数组变成一个升序数组? 如n=6,m=3 1 3 5 2 4 6 1 2 3 4 5 6 排序前 排序后 #include <algorithm> #include <iostream> #include <cstring> #include <vector> #include <cstdio> #include <cmath> #include &

从0开始学算法--排序(1.8桶排序)

算法理解: 桶排序是对计数排序的一种优化,在计数排序中x应该放在计数数组下表为x的位置上,这样如果重复数字较少,计数数组每个位置的利用率就非常小. 桶排序是将一系列大小近似的数字放在一个位置(每个桶维护一条有序的链表),这样提高每个位置的利用率,以提高效率. 以A[]={1,21,23,41,49}为例 假设每个桶里有10中元素,那么桶排序的结构如下图所示. #include <algorithm> #include <iostream> #include <cstring&

0基础学算法 第二弹 排序

大家好啊,这是0算法基础学算法系列第二篇,上次我在第一弹里讲了关于流程图的内容,我寻思着,这次讲些什么好呢,于是我决定,教大家一个很基础的算法,那就是排序,排序有很多方法,如果你有更多方法请在评论区里留言哦. 排序在程序中特别实用,常用的有快速排序,桶排序,冒泡排序,插入排序等等,在这里我不建议使用冒泡排序或者插入排序,建议桶排序和快速排序,这两个排序非常实用,时间复杂度低,理解起来也很容易,首先,你先思考一下,怎么用程序进行排序,然后你再来看看你的思路合理不合理,最后试着用程序实现它,实现后你

从0开始学算法--数据结构(2.3队列)

顾名思义:队列就像排序一样,先排队的人先得到处理 队列与栈类似:队列是一个先进先出表 首先考虑数组模拟,如果线性数组模拟,会导致占用空间过多,为什么?数组模拟栈会遇到这样的问题吗? 因为队列是一个先进先出表,比如加入5个元素占用的是数组下表的0-4号位置,这时候删除两个元素,0-1号位置.为了维护这个队列的结构就会导致0-1号位置占用但不利用. 栈取出的是数组尾部的元素,所以不会占用额外的空间. 优化:“将数组变为环形”(模的意义). 如果我们每次加入元素是给数组下表取模,那么整个数组就变成了环

从0开始学算法--基础数据结构(2.8并查集)

算法理解: 根据名字就能很好的理解这个算法,集合的合并和查询 合并什么?查询什么? 合并操作为:把x所在的集合和y所在的集合合并为一个集合.查询x和y是否在一个集合里. 如:元素为1-n,这n个元素分别在编号为1-n的集合中.如果将3和5合并成为一个集合,只需要将元素3指向元素5即可 现在把元素5和元素2所在的集合合并合并,5指向2 可以看到如果要查询2和3是不是在一个集合中,只需要查询2和3的祖先是不是同一个元素就可以了 查询祖先代码 //f[x]初始化为f[i]=i; int find_se

从0开始学算法--数据结构(2.4双端队列与单调队列)

双端队列是特殊的队列,它与队列不同的是可以将元素加入头或尾,可以从头或尾取出元素(滑稽-这部就是栈和队列结合了吗). c++标准库 头文件 #include<deque> 定义 deque<int>deq; 取出队头,尾元素 deq.pop_front(); deq.pop_back(); 访问队头,尾元素 deq.front(); deq.back(); 向队头,尾加入元素 deq.push_front(x); deq.push_back(x); 单调队列是在队列的基础上使它保持

0基础学算法 第五弹 填坑

这个填坑系列,是为了能够解决大家在前面的疑点,如果你在前面有哪些疑点,可以加入QQ群1031467671,群名称叫球君博客的填坑群,入群问题答案是 球君,我要是在博客里有什么不足的,或着有什么讲的不清楚的地方,可以进去发表建议,好今天这期我就来填坑了,昨天有人说第四弹的乘法思路没讲清楚,所以今天我重新讲讲. 乘法的思路简单的说就是还是依靠竖式的原理,有第二个数的第一位乘上上面的全部数,再让第二个数的第二位乘上上面所有的数,这个操作用一个嵌套循环就可以完成了,再是进位问题,这个进位和加法有些不同,

算法--排序--分治与快速排序

学习排序算法也有一段时间,一直没有好好整理下排序算法的相关知识,排序在算法中是最基础也是最重要的,所以有必要自己进行一番整理,在提高领悟算法本质的同时以备以后自己复习,顺便也将自己领悟到的一些思想进行记录. 下面简单整理下快排的算法感悟,当然,个人觉得领悟快排的核心思想分治才是学习这个算法的最重要目的. 一.快排的思想 1.分治思想.是的,快排最核心的思想就是:递归中重要的思想,分治.好吧,其实刚刚接触分治的时候,或者说递归的时候,我真的真的无法真正理解,感觉就是:好像理解了,但是细想又觉得有困