目录
  1. 1. 快速排序
    1. 1.1. 题目描述
      1. 1.1.0.1. 输入格式
      2. 1.1.0.2. 输出格式
      3. 1.1.0.3. 数据范围
      4. 1.1.0.4. 输入样例:
      5. 1.1.0.5. 输出样例:
  2. 1.2. 题目分析
    1. 1.2.1. 原理
  3. 1.3. 代码实现
  4. 1.4. 运行结果
  5. 1.5. 实例
    1. 1.5.1. 第k个数
    2. 1.5.2. 题目描述
      1. 1.5.2.1. 输入格式
      2. 1.5.2.2. 输出格式
      3. 1.5.2.3. 数据范围
      4. 1.5.2.4. 输入样例:
      5. 1.5.2.5. 输出样例:
    3. 1.5.3. 题目分析
  6. 1.6. 总结
快速排序

快速排序

题目描述

给定你一个长度为n的整数数列。

请你使用归并排序对这个数列按照从小到大进行排序。

并将排好序的数列按顺序输出。

输入格式

输入共两行,第一行包含整数 n。

第二行包含 n 个整数(所有整数均在$1$ ~$ 10^9$范围内),表示整个数列。

输出格式

输出共一行,包含 n 个整数,表示排好序的数列。

数据范围

$1≤n≤1000001≤n≤100000$

输入样例:

5
3 1 2 4 5

输出样例:

1 2 3 4 5

题目分析

采用快排实现。分析快排原理

原理

  1. 确定分界点
    • 左端点a[l]
    • 右端点a[r]
    • 中间点a[l + r >> 1]
  2. 调整的区间
  3. 递归处理左右两边
    • 左边排序
    • 右边排序
    • 组装一块儿

代码实现

#include<iostream>
using namespace std;

const int N = 1e6 + 10;

int n;
int a[N];

void quick_sort(int l, int r, int a[]){
//1.判断边界问题,如果只有一个数则直接返回
if(l >= r) return;
//确定分界点,与左右指针
int x = a[l], i = l - 1, j = r + 1;
//2.调整两边区间,判断左右指针是否交叉相遇
while(i < j)
{
do i++; while (a[i] < x);
do j--; while (a[j] > x);
// 分别查找左右两边元素,找到不符合条件的交换
if(i < j) swap(a[i], a[j]);
}
// 递归处理左右两边
quick_sort(l, j, a);
quick_sort(j+1, r, a);
}

int main(){
//输入元素个数
scanf("%d", &n);
//填充数组
for(int i = 0; i < n; i++)
scanf("%d", &a[i]);
//快排
quick_sort(0, n - 1, a);
//打印数组
for(int i = 0; i < n; i++)
printf("%d ", a[i]);
}

运行结果

输入

8
3 1 2 4 5 6 10 7

输出

1 2 3 4 5 6 7 10 

实例

第k个数

题目描述

给定一个长度为n的整数数列,以及一个整数k,请用快速选择算法求出数列的第k小的数是多少。

输入格式

第一行包含两个整数 n 和 k。

第二行包含 n 个整数(所有整数均在1~109109范围内),表示整数数列。

输出格式

输出一个整数,表示数列的第k小数。

数据范围

$1≤n≤100000$
$1≤k≤n$

输入样例:

5 3
2 4 1 5 3

输出样例:

3

题目分析

同样首先通过快排得到结果,然后按照顺序找对应的数据即可

总结

对于快速排序,要寻找都一个分界点,这个分界点可以是边界值,也可以是中间值。其次是对左右两端的处理,就是将左右两端同样看作一个新的数组,再次按照方法重复进行分支,分支后的左边最大的值永远是小于右边最小的值

文章作者: Jachie Xie
文章链接: https://xjc5772.github.io/2020-03/04/%E7%AE%97%E6%B3%95/%E5%BF%AB%E9%80%9F%E6%8E%92%E5%BA%8F/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 XJC&Blog
打赏
  • 微信
  • 支付宝

评论