【算法】

  选取pivot,然后每趟快排用双指针扫描(l,r)区间,交换左指针大于pivot的元素和右指针小于pivot的元素,将区间分成大于pivot和小于pivot的

【注意】

  时间复杂度取决于pivot的选取是否能把(l,r)区间分成长度相等的两个子区间。

  最优:O(nlogn)  最差:O(n2)

  问题解决:

  1. 版本一:pivot选择区间中间的元素可以解决数组本身就已经排好序的问题,但是无法解决数组中每个元素均相等(第五个点tle)
 #include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5;
int n,p,i,j;
int a[maxn];
void quick_sort(int l,int r)
{
if(l>r) return;
i = l, j = r;
//swap(a[l], a[(l+r)>>]); ------pivot选区间中间的元素
while(i < j) {//i和j相等时停下来
while(a[j]>=a[l] && i < j) j--; //先右再左很关键!若右指针和左指针相遇则此时左指针指向pivot或小于pivot的元素(前一次有交换),若左指针和右指针相遇,则此时
while(a[i]<=a[l] && i < j) i++; //右指针应当已经寻找到的小于pivot的元素;若先左再右,则反过来了。pivot的位置会出错。
if(i<j) swap(a[i],a[j]);
}
swap(a[l],a[j]);
quick_sort(l,i-);
quick_sort(i+,r);
}
int main()
{
cin>>n;
for(int i = ; i <= n; i++)
cin>>a[i];
quick_sort(,n);
for(int i = ; i <= n; i++)
cout << a[i] << " ";
return ;
}

    2、版本二:先判断是否有序,若有序则结束,若无序再按原方法。

    3、版本三:每次分成两个子区间,左区间小于等于pivot,右区间大于等于pivot,但不一定确定好pivot的位置,但最终区间长度为2或3的时候必定能确定好

        ------------------------感觉这种要好写一点,理解了之后,其实都是细节------------------------

 #include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5;
int n,p,i,j;
int a[maxn];
void quick_sort(int l,int r)
{
int pivot = a[(l+r)>>];
i = l, j = r;
while(i <= j) { //直到i>j为止,就算数组元素均相等也会向前推进
while(a[i] < pivot) i++;
while(a[j] > pivot) j--;
if(i <= j) {
swap(a[i],a[j]);
i++, j--;
}
}
if(i < r) quick_sort(i,r);
if(j > l) quick_sort(l,j);
}
int main()
{
cin>>n;
for(int i = ; i <= n; i++)
cin>>a[i];
quick_sort(,n);
for(int i = ; i <= n; i++)
cout << a[i] << " ";
return ;
}

    4、找第k大的数:分治法类似快排的方法,平均复杂度O(n)【1+2+4+。。。+n/2+n】按版本三的话不太好写,就按版本一来吧:

 #include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5;
int n,k,i,j;
int a[maxn];
int quick_find(int l,int r,int k)
{
int pivot = a[(l+r)>>], rec = ;
i = l, j = r;
swap(a[(l+r)>>], a[l]);
while(i < j) {
while(a[j] >= pivot && i < j) j--, rec++;
while(a[i] <= pivot && i < j) i++;
if(i < j) swap(a[i],a[j]);
}
swap(a[i],a[l]);
if(k == rec + ) return a[i];
else if(k <= rec) return quick_find(i+,r,k);
else return quick_find(l, i-, k-rec-); }
int main()
{
cin>>n>>k;
for(int i = ; i <= n; i++)
cin>>a[i];
cout<<quick_find(,n,k)<<endl;
return ;
}

 

luogu_P1177 【模板】快速排序 (快排和找第k大的数)的更多相关文章

  1. 快排法求第k大

    快排法求第k大,复杂度为O(n) import com.sun.media.sound.SoftTuning; import java.util.Arrays; import java.util.Ra ...

  2. 找第k大的数

    (找第k大的数) 给定一个长度为1,000,000的无序正整数序列,以及另一个数n(1<=n<=1000000),接下来以类似快速排序的方法找到序列中第n大的数(关于第n大的数:例如序列{ ...

  3. P1049 找第K大的数

    题目描述 给定一个无序正整数序列, 以及另一个数n (1<=n<=1000000), 然后以类似快速排序的方法找到序列中第n大的数(关于第n大的数:例如序列{1,2,3,4,5,6}中第3 ...

  4. 快速排序算法的实现 && 随机生成区间里的数 && O(n)找第k小 && O(nlogk)找前k大

    思路:固定一个数,把这个数放到合法的位置,然后左边的数都是比它小,右边的数都是比它大 固定权值选的是第一个数,或者一个随机数 因为固定的是左端点,所以一开始需要在右端点开始,找一个小于权值的数,从左端 ...

  5. 找出N个无序数中第K大的数

    使用类似快速排序,执行一次快速排序后,每次只选择一部分继续执行快速排序,直到找到第K个大元素为止,此时这个元素在数组位置后面的元素即所求 时间复杂度: 1.若随机选取枢纽,线性期望时间O(N) 2.若 ...

  6. 找出整数中第k大的数

    一  问题描述: 找出 m 个整数中第 k(0<k<m+1)大的整数. 二  举例: 假设有 12 个整数:data[1, 4, -1, -4, 9, 8, 0, 3, -8, 11, 2 ...

  7. 基于快速排序思想partition查找第K大的数或者第K小的数。

    快速排序 下面是之前实现过的快速排序的代码. function quickSort(a,left,right){ if(left==right)return; let key=partition(a, ...

  8. 寻找第K大的数(快速排序的应用)

    有一个整数数组,请你根据快速排序的思路,找出数组中第K大的数.给定一个整数数组a,同时给定它的大小n和要找的K(K在1到n之间),请返回第K大的数,保证答案存在.测试样例:[1,3,5,2,2],5, ...

  9. 算法题之找出数组里第K大的数

    问题:找出一个数组里面前K个最大数. 解法一(直接解法): 对数组用快速排序,然后直接挑出第k大的数.这种方法的时间复杂度是O(Nlog(N)).N为原数组长度. 这个解法含有很多冗余,因为把整个数组 ...

随机推荐

  1. [CF1161C] Thanos Nim

    传送门 题意:\(2n\)堆石子,每堆\(a_i\)个,先手每次选中\(n\)堆石子,并从每堆中拿走任意个(可以不同).轮到某人时不足\(n\)堆则判负,问先手是否必胜.\(n\leq25,a_i\l ...

  2. 计算两个GPS坐标的距离

    场景:已知两个GPS点的经纬度坐标信息.计算两点的距离. 1. 距离/纬度关系 GPS: 22.514519,113.380301 GPS: 22.511962,113.380301 距离: 284. ...

  3. 【leetcode】1095. Find in Mountain Array

    题目如下: (This problem is an interactive problem.) You may recall that an array A is a mountain array i ...

  4. 第七周作业—N42-虚怀若谷

    一.简述OSI七层模型和TCP/IP五层模型 1. OSI七层模型 物理层:二进制传输,为启动.维护以及关闭物理链路定义了电气规范.机械规范.过程规范和功能规范:实际的最终信号的传输是通过物理层实现的 ...

  5. python-globals()、locals()的使用

    globals() 函数返回一个全局变量的字典,包括所有导入的变量locals() 函数返回一个当前位置的所有局部变量的字典print(globals())print(locals()) global ...

  6. springboot2.0+mysql整合mybatis,发现查询出来的时间比数据库datetime值快了8小时

    参考:https://blog.csdn.net/lx12345_/article/details/82020858 修改后查询数据正常

  7. 3D Computer Grapihcs Using OpenGL - 08 Text File Shaders

    使用之前的方法写Shader是一件很痛苦的事情,把Shader代码直接卸载C++文件中,需要使用很多引号来包裹,既不美观也不方便. 我们这节的目的是使用纯文本文件保存Shader. 首先在工程中创建两 ...

  8. D. White Lines

    D. White Lines 给定一个$n\times n$的$WB$矩阵,给定一个$k*k$的能把$B$变成$W$的橡皮擦,求橡皮擦作用一次后,全为$W$的行.列总数最大值 前缀和差分 #inclu ...

  9. C/C++中动态内存分配

    代码段:用来存放程序执行代码的一块内存区域.这部分内存大小在程序运行前已经知道,通常属于只读,其中包括只读的字符串常量,不可改变 BBS段:用来存放存放程序中未初始化的全局变量及静态变量,属于静态内存 ...

  10. 记一次SQL Server delete语句的优化过程

    今天测试反应问题,性能测试环境一个脚本执行了3个小时没有出结果,期间其他dba已经建立了一些索引但是没有效果. 语句: DELETE T  from License T  WHERE exists ( ...