当前位置:网站首页>冒泡排序、选择排序、插入排序、快速排序
冒泡排序、选择排序、插入排序、快速排序
2022-07-30 05:42:00 【就是叫这个名字】
整理自视频,侵删:https://www.bilibili.com/video/BV15b4y117RJ?spm_id_from=333.999.0.0
一、冒泡排序
冒泡排序文字描述(以升序为例):
1.依次比较数组中相邻两个元素的大小,若a[j]>a[j+1],则交换连个元素,两两都比较一遍称为一轮冒泡,结果是让最大的元素排至最后
2.重复以上步骤,直至整个数组有序
冒泡排序是一种稳定的排序算法
代码:
public static int[] swap(int[] a,int i,int j){
int temp=a[i];
a[i]=a[j];
a[j]=temp;
return a;
}
//平均时间复杂度O^2
public static int[] bubble(int[] a){
for(int j=0;j<a.length-1;j++){
boolean swapped=false; //是否交换
for(int i=0;i<a.length-1-j;i++){
if(a[i]>a[i+1]){
swap(a,i,i+1);
swapped=true;
}
}
if(!swapped){
break;
}
}
return a;
}
//平均时间复杂度O^2,在有序的情况下是O(只需要进行一轮冒泡)
public static int[] bubble_v2(int[] a){
while(true){
int last=a.length-1; //最后一次交换的索引
for(int i=0;i<last;i++){
if(a[i]>a[i+1]){
swap(a,i,i+1);
last=i;
}
}
if(last==0){
break;
}
}
return a;
}
二、选择排序
选择排序文字描述(以升序为例):
1.将数组分为两个子集,排序的和未排序的,每一轮从未排序的子集中选出最小的元素,放入排序子集
2.重复以上步骤,直至整个数组有序
选择排序是一种不稳定的排序算法
//在有序度高的情况下,冒泡优秀于选择
//平均时间复杂度O^2 ,一般情况选择优于冒泡,因为冒泡排序交换次数多,
public static int[] select(int[] a){
for(int j=0;j<a.length-1;j++){
int min=j;
for(int i=min+1;i<a.length-1;i++){
if(a[i]<a[min]){
min=i;
}
}
if(min!=j){
swap(a,min,j); //优化:为减少交换次数,每一轮可以先找最小的索引,在每轮最后再交换元
//素
}
}
return a;
}
三、插入排序
插入排序文字描述(以升序为例):
1.将数组分位两个区域,排序区域和未排序区域,每一轮从未排序区域中取出第一个元素,插入到排序区域(需要保证顺序)
2.重复以上步骤,直至整个数组有序
插入排序是一种稳定的排序算法
优化方式:
1.待插入元素进行比较时,遇到比自己小的元素,就代表找到了插入位置,无需进行后续比较
2.插入时可以直接移动元素位置,而不是交换元素
与选择排序比较:
1.二者时间复杂度都是O(n^2)
2.大部分情况下,插入略优于选择
3.有序集合插入的时间复杂度为O(n)
4.插入排序属于有序的排序算法,而选择属于不稳定排序
代码:
public static int[] insert(int[] a){
for(int i=1;i<a.length;i++){
int j=i-1;
int t =a[i];
while(j>=0){
if(t<a[j]){
a[j+1]=a[j];
}else{
break; //退出循环,减少比较次数
}
j--;
}
a[j+1]=t;
}
return a;
}
四、快速排序
快速排序文字描述:
1.每一轮排序选择一个基准点,进行分区
(1)让小于基准点的元素的进入一个分区,大于基准点的元素的进入另一个分区
(2)当分区完成时,基准点元素的位置就是其最终位置
2.在子分区内重复以上过程,直至子分区元素个数小于等于1
单边循环-快速排序
单边循环快速排序(lomuto洛穆托分区方案)
1.选择最右边的元素作为基准点元素
2.j 指针负责找到比基准点元素小的元素,一旦找到则与i进行交换
3.i 指针维护小于基准点元素的边界,也是每次交换的目标索引
4.最后基准点与i交换,i即为分区位置
代码:
public static void quick(int[] a,int l,int h){
if(l>=h){
return;
}
int p = partition1(a,l,h); // p:基准点的索引值
quick(a,l,p-1); //左边分区的范围确定
quick(a,p+1,h); //右边分区的范围确定
}
//单边循环——分区
public static int partition1(int[] a,int l,int h){
//l,h分区的上下边界
//返回值代表了基准点元素所在的正确索引,用它确定下一轮分区的上下边界
int pv=a[h]; //基准点元素
int i=l;
for(int j=l;j<h;j++){
if(a[j]<pv){
if(i!=j){
swap(a,i,j); //优化:加个判断条件
}
i++;
}
}
if (i!=h){
swap(a,h,i); //优化:加个判断条件
}
return i;
}
双边循环-快速排序
双边循环快速排序(并不完全等价于hoare霍尔分区方案)
1.选择最左边的元素作为基准点元素
2.j 指针负责从右向左找比基准点小的元素,i指针负责从左向右找比基准点大的元素,一旦找到二者交换,直至i, j相交
3.最后记住那点与i(此时i与j相等)交换,i即为分区位置
public static void quick(int[] a,int l,int h){
if(l>=h){
return;
}
int p = partition1(a,l,h); // p:基准点的索引值
quick(a,l,p-1); //左边分区的范围确定
quick(a,p+1,h); //右边分区的范围确定
}
//双边循环——分区
public static int partition2(int[] a,int l,int h){
//l,h分区的上下边界
//返回值代表了基准点元素所在的正确索引,用它确定下一轮分区的上下边界
int pv=a[l]; //基准点元素
int i=l;
int j=h;
while(i<j){
//基准点在左边,先循环j,后循环i,顺序不可颠倒
// j从右找比基准点元素小的元素
while(i<j && a[j]>pv){
j--;
}
// i从左找比基准点元素大的元素
while(i<j && a[i]<=pv){
//i<j why? --避免基准点元素被错误地交换
i++;
}
swap(a,i,j);
}
swap(a,l,j); //此时i==j
return j;
}
快速排序特点
1.平均时间复杂度是O(nlog2n),最坏时间复杂度O(n^2)
2.数据量较大时,优势非常明显
3.属于不稳定排序
若数组中重复元素很多,则快排优势减小
边栏推荐
猜你喜欢
Remember a traffic analysis practice - Anheng Technology (August ctf)
![Monstache执行monstache -f config.toml出错No processor type exists with name [attachment] [type=parse_exc](/img/2d/50c9001125cd613087044d2b6c78b1.png)
Monstache执行monstache -f config.toml出错No processor type exists with name [attachment] [type=parse_exc
awd --waf deployment

sqli-labs靶场 SQL注入学习 Less-1

TypeError The view function did not return a valid response. The function either returned None 的解决
![[Net Ding Cup 2020 Qinglong Group] AreUSerialz](/img/f2/9aef8b8317eff31af2979b3a45b54c.png)
[Net Ding Cup 2020 Qinglong Group] AreUSerialz

3分钟告诉你如何成为一名黑客|零基础到黑客入门指南,你只需要掌握这五点能力

强国杯初赛WP

Koa2框架快速入门与基本使用

【小程序项目开发-- 京东商城】uni-app之分类导航区域
随机推荐
misc-log analysis of CTF
php漏洞全解
运算符和交互基础
PHP-fpm
【调优】一个 Spark 任务某天突然变慢怎么解决
sqli-labs靶场 SQL注入学习 Less-1
Monstache执行monstache -f config.toml出错No processor type exists with name [attachment] [type=parse_exc
Volatility memory forensics - command shows
CTFSHOW命令执行【web29-web124】未完待续
volatility内存取证----命令演示
Arrays工具类的使用
[Net Ding Cup 2020 Qinglong Group] AreUSerialz
async/await用法详解
简述SSRF
CTF之misc-图片隐写
c#下Web3合约空投、转账调用代码
浏览器缓存
【无标题】ES5新特性
vulnhub-XXE ctf security question
npm run serve启动报错npm ERR Missing script “serve“