题目描述

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

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

输入输出格式

输入格式:

输入文件sort.in的第1行为一个正整数N,第2行包含N个空格隔开的正整数a[i],为你需要进行排序的数,数据保证了A[i]不超过1000000000。

输出格式:

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

输入输出样例

输入样例#1: 复制

5
4 2 4 5 1
输出样例#1: 复制

1 2 4 4 5

说明

对于20%的数据,有N≤1000;

对于100%的数据,有N≤100000。

分类 ------------ 内部比较排序
数据结构 --------- 数组
最差时间复杂度 ---- 每次选取的基准都是最大(或最小)的元素,导致每次只划分出了一个分区,需要进行n-1次划分才能结束递归,时间复杂度为O(n^2)
最优时间复杂度 ---- 每次选取的基准都是中位数,这样每次都均匀的划分出两个分区,只需要logn次划分就能结束递归,时间复杂度为O(nlogn)
平均时间复杂度 ---- O(nlogn)
所需辅助空间 ------ 主要是递归造成的栈空间的使用(用来保存left和right等局部变量),取决于递归树的深度,一般为O(logn),最差为O(n)
稳定性 ---------- 不稳定
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 100010
using namespace std;
int n;
int num[MAXN];
int main(){
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",&num[i]);
sort(num+,num++n);
for(int i=;i<=n;i++)
cout<<num[i]<<" ";
}

sort的快速排序

分类 -------------- 内部比较排序
数据结构 ---------- 数组
最差时间复杂度 ---- O(n^2)
最优时间复杂度 ---- 如果能在内部循环第一次运行时,使用一个旗标来表示有无需要交换的可能,可以把最优时间复杂度降低到O(n)
平均时间复杂度 ---- O(n^2)
所需辅助空间 ------ O(1)
稳定性 ------------ 稳定
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 100010
using namespace std;
int n,num[MAXN];
int main(){
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",&num[i]);
for(int j=;j<=n;j++)
for(int i=;i<=n-j;i++)
if(num[i]>num[i+])
swap(num[i],num[i+]);
for(int i=;i<=n;i++) cout<<num[i]<<" ";
}

冒泡排序 n^2

分类 -------------- 内部比较排序
数据结构 ---------- 数组
最差时间复杂度 ---- O(n^2)
最优时间复杂度 ---- 如果序列在一开始已经大部分排序过的话,会接近O(n)
平均时间复杂度 ---- O(n^2)
所需辅助空间 ------ O(1)
稳定性 ------------ 稳定
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 100010
using namespace std;
int n,num[MAXN];
int l,r;
int main(){
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",&num[i]);
l=;r=n;
while(l<r){
for(int i=l;i<r;i++)
if(num[i]>num[i+])
swap(num[i],num[i+]);
r--;
for(int i=r;i>l;i--)
if(num[i-]>num[i])
swap(num[i],num[i-]);
l++;
}
for(int i=;i<=n;i++) cout<<num[i]<<" ";
}

改良版的冒泡排序(鸡尾酒排序)

分类 -------------- 内部比较排序
数据结构 ---------- 数组
最差时间复杂度 ---- O(n^2)
最优时间复杂度 ---- O(n^2)
平均时间复杂度 ---- O(n^2)
所需辅助空间 ------ O(1)
稳定性 ------------ 不稳定
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 100010
using namespace std;
int n,num[MAXN];
int main(){
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",&num[i]);
for(int i=;i<=n;i++){
int minn=i;
for(int j=i+;j<=n;j++)
if(num[j]<num[minn])
minn=j;
if(minn!=i) swap(num[i],num[minn]);
}
for(int i=;i<=n;i++) cout<<num[i]<<" ";
}

选择排序

分类 ------------- 内部比较排序
数据结构 ---------- 数组
最差时间复杂度 ---- 最坏情况为输入序列是降序排列的,此时时间复杂度O(n^2)
最优时间复杂度 ---- 最好情况为输入序列是升序排列的,此时时间复杂度O(n)
平均时间复杂度 ---- O(n^2)
所需辅助空间 ------ O(1)
稳定性 ------------ 稳定
插入

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 100010
using namespace std;
int n,num[MAXN];
int main(){
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",&num[i]);
for(int i=;i<=n;i++){
int get=num[i];
int j=i-;
while(j>=&&num[j]>get){
num[j+]=num[j];
j--;
}
num[j+]=get;
}
for(int i=;i<=n;i++) cout<<num[i]<<" ";
}

排序

分类 -------------- 内部比较排序
数据结构 ---------- 数组
最差时间复杂度 ---- O(n^2)
最优时间复杂度 ---- O(nlogn)
平均时间复杂度 ---- O(n^2)
所需辅助空间 ------ O(1)
稳定性 ------------ 稳定
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 100010
using namespace std;
int n,num[MAXN];
int main(){
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",&num[i]);
for(int i=;i<=n;i++){
int get=num[i];
int l=,r=i-;
while(l<=r){
int mid=(l+r)/;
if(num[mid]>get) r=mid-;
else l=mid+;
}
for(int j=i-;j>=l;j--)
num[j+]=num[j];
num[l]=get;
}
for(int i=;i<=n;i++) cout<<num[i]<<" ";
}

二分的插入排序

分类 -------------- 内部比较排序
数据结构 ---------- 数组
最差时间复杂度 ---- O(nlogn)
最优时间复杂度 ---- O(nlogn)
平均时间复杂度 ---- O(nlogn)
所需辅助空间 ------ O(n)
稳定性 ------------ 稳定
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 100010
using namespace std;
int n,num[MAXN],tmp[MAXN];
void up(int l,int mid,int r){
int len=r-l+;
int i=l,j=mid+,tot=;
while(i<=mid&&j<=r){
tmp[++tot]=num[i]<num[j]?num[i++]:num[j++];
}
while(i<=mid) tmp[++tot]=num[i++];
while(j<=r) tmp[++tot]=num[j++];
for(int k=;k<=tot;k++)
num[l++]=tmp[k];
}
void work1(int l,int r){
if(l==r) return ;
int mid=(l+r)/;
work1(l,mid);
work1(mid+,r);
up(l,mid,r);
}
int main(){
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",&num[i]);
work1(,n);//递归版本
for(int i=;i<=n;i++) cout<<num[i]<<" ";
}

递归版的归并排序

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 100010
using namespace std;
int n,num[MAXN],tmp[MAXN];
void up(int l,int mid,int r){
int len=r-l+;
int i=l,j=mid+,tot=;
while(i<=mid&&j<=r){
tmp[++tot]=num[i]<num[j]?num[i++]:num[j++];
}
while(i<=mid) tmp[++tot]=num[i++];
while(j<=r) tmp[++tot]=num[j++];
for(int k=;k<=tot;k++)
num[l++]=tmp[k];
}
int main(){
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",&num[i]);
int l,r,mid;
for(int i=;i<=n;i*=){
l=;
while(l+i<=n){
mid=l+i-;
r=mid+i<=n?mid+i:n;
up(l,mid,r);
l=r+;
}
}
for(int i=;i<=n;i++) cout<<num[i]<<" ";
}

非递归版本的归并排序

分类 ------------ 内部非比较排序
数据结构 --------- 数组
最差时间复杂度 ---- O(n + k)
最优时间复杂度 ---- O(n + k)
平均时间复杂度 ---- O(n + k)
所需辅助空间 ------ O(n + k)
稳定性 ----------- 稳定
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 100010
using namespace std;
int tmp[MAXN];
int n,maxn,num[MAXN];
int main(){
scanf("%d",&n);
for(int i=;i<=n;i++){
scanf("%d",&num[i]);
tmp[num[i]]++;
maxn=max(maxn,num[i]);
}
for(int i=;i<=maxn;i++)
while(tmp[i]){
cout<<i<<" ";
tmp[i]--;
}
}

桶排序

其他的就没有什么用了吧,等以后有时间再整理。

洛谷 P1177 【模板】快速排序(排序算法整理)的更多相关文章

  1. 洛谷.3809.[模板]后缀排序(后缀数组 倍增) & 学习笔记

    题目链接 //输出ht见UOJ.35 #include<cstdio> #include<cstring> #include<algorithm> const in ...

  2. 排序算法整理C++(初赛)

    排序算法整理 常见考点 将一个乱掉的字符串排回有序(以交换为基本操作)的最少操作,就是冒泡排序. 排序算法的稳定性 排序算法的时间复杂度 排序算法的稳定性 稳定性是指排序前两个元素a1 = a2,a1 ...

  3. 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)

    To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...

  4. (排序算法整理)NEFU 30/32

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/caihongshijie6/article/details/26165093        事实上, ...

  5. 洛谷P1155 双栈排序题解(图论模型转换+二分图染色+栈)

    洛谷P1155 双栈排序题解(图论模型转换+二分图染色+栈) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1311990 原题地址:洛谷P1155 双栈排序 ...

  6. 洛谷 P1177 【模板】快速排序【13种排序模版】

    P1177 [模板]快速排序 题目描述 利用快速排序算法将读入的N个数从小到大排序后输出. 快速排序是信息学竞赛的必备算法之一.对于快速排序不是很了解的同学可以自行上网查询相关资料,掌握后独立完成.( ...

  7. 常用的 JS 排序算法整理

    关于排序算法的问题可以在网上搜到一大堆,但是纯 JS 版比较零散,之前面试的时候特意整理了一遍,附带排序效率比较. //1.冒泡排序 var bubbleSort = function(arr) { ...

  8. 洛谷P3375 [模板]KMP字符串匹配

    To 洛谷.3375 KMP字符串匹配 题目描述 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next.如果 ...

  9. 【AC自动机】洛谷三道模板题

    [题目链接] https://www.luogu.org/problem/P3808 [题意] 给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过. [题解] 不再介绍基础知识了,就是裸的模 ...

  10. 洛谷-P5357-【模板】AC自动机(二次加强版)

    题目传送门 -------------------------------------- 过年在家无聊补一下这周做的几道AC自动机的模板题 sol:AC自动机,还是要解决跳fail边产生的重复访问,但 ...

随机推荐

  1. HDU-1541 Stars 树状数组

    题目链接:https://cn.vjudge.net/problem/HDU-1541 题意 天上有许多星星 现给天空一个平面坐标轴,统计每个星星的level, level是指某一颗星星的左下角(x& ...

  2. HDU2452 Navy maneuvers 记忆化搜索

    这题目意思能忍?读了半年,乱七八糟的 记忆化搜索 拖拖的,dp[i][0]代表以获得最小值为目标的船以i为起点.dp[i][1]代表以获得最大值为目标的船以i为起点.接下来暴力枚举入度为0的点为起点, ...

  3. EChart报表插件使用笔记(1)

    报表插件Echart java类 package com.spring.controller; import java.io.IOException; import java.util.Arrays; ...

  4. Zookeeper简单概念介绍

    过去,每个应用都是一个CPU.一个主机上的单一系统.然而今天,随着大数据和云计算时代的到来,不论什么相互独立的程序都可以运行在多个计算机上.然而面临的问题是,协调这些集群的系统比在单一主机上要复杂的多 ...

  5. UITextField监控文字变化方法

    项目里须要在不隐藏键盘的情况下.来更改button 的状态. 这里就是要对uitextfield监控.uitextfield继承于UIControl.所以能够 使用addTarget方法.详细例如以下 ...

  6. VB.NET中文双引号的处理方法

    相信朋友们也都碰到了这样的问题了,VS的IDE会不分青红皂白的把中文双引号变成英文的双引号,当然可以通过关闭自动重排功能来回避这个问题,但不是一个好的解决办法,以下这个方式不错: 如果在实际的使用中我 ...

  7. HUE配置文件hue.ini 的filebrowser模块详解(图文详解)(分HA集群和非HA集群)

    不多说,直接上干货! 我的集群机器情况是 bigdatamaster(192.168.80.10).bigdataslave1(192.168.80.11)和bigdataslave2(192.168 ...

  8. Android控件-Fragment+ViewPager(高仿微信界面)

    什么是Fragment? Fragment是Android3.0后新增的概念,Fragment名为碎片,不过却和Activity十分相似,具有自己的生命周期,它是用来描述一些行为或一部分用户界面在一个 ...

  9. Android控件-单选按钮RadioButton

    RadioGroup单选按钮用法,还是先看效果图 先中后,点RadioGroup测试按钮,可在标题栏显示选择结果,点清除可以清除选择.下面上代码,main.xml: <RadioGroup an ...

  10. 手把手教你如何在Ubuntu系统中安装Pycharm

    前几天带大家一起安装了Ubuntu14.04系统,没来得及上车的伙伴可以戳这篇文章:手把手教你在VMware虚拟机中安装Ubuntu14.04系统.今天小编带大家一起在Ubuntu14.04中安装Py ...