选择排序和冒泡排序区别以及冒泡排序优化

7 篇文章 0 订阅

简单选择排序和冒泡排序区别

我一直搞不太清这两个具体区别。打算研究下。

我认为两种主要区别是(有不同意见请告知):冒泡每次循环都是相邻两数的比较(内层循环都是j和j+1比较),选择排序是某一下标元素与其他下标元素依次比较(内层循环是i和j的比较)。


一、冒泡排序

依次对相邻两数作比较,若前面的大于后面的,则交换。

第一次循环后,最大的数已经出现在最后的。

第二次循环后,第二大的数在倒数第二的位置上。

依此循环,知道数组有序。排序过程如下:


public static void sort(int[] a){
int len = a.length;
for(int i = 0; i< len; i++){        //控制循环的次数。
for(int j = 0; j<len-i-1;j++){    //控制比较数的下标。
if(a[j]>a[j+1]){
swap(a, j, j+1);
}

System.out.print("i = " +i+", j = "+j+"    ");
print(a);
}
}
}

private static void swap(int[]a, int i, int j ){
int temp = a[i];
a[i] = a[j];
a[j]= temp;
}


优化1:控制外层循环的次数


对上述冒泡方法可以进行优化,就是定义个标记,来辅助控制外层循环的次数。

/**
* 使用标志位来控制外层循环的次数
* @param a
*/
public static void sort1(int[] a){
int len = a.length;
boolean flag = true;    //控制外层循环次数,若数组已经有序了,就不比较了。
for(int i = 0; i< len; i++){    
flag = true;
for(int j = 0; j<len-i-1;j++){    
if(a[j]>a[j+1]){
flag = false;
swap(a, j, j+1);
}
}
if(flag){
break;
}
}
}


优化2:在上面进一步,控制内外层循环的次数。

第二种方法是参考此文。

/**
* 记录上次交换的位置,以此为内层循环的界限。
* @param a
*/
public static void sort2(int[] a){
int len = a.length;
boolean flag = true;    //控制外层循环次数,若数组已经有序了,就不比较了。
int lasttemp = len-1;
for(int i = 0; i< len; i++){    
flag = true;
int last = lasttemp;
for(int j = 0; j<last;j++){    
if(a[j]>a[j+1]){
flag = false;
swap(a, j, j+1);
lasttemp =j;  //记录最后以此交换的位置。此位置之后为有序的。
}
}
if(flag){
break;
}
}
}


二、简单选择排序:

从第一个元素开始,与后续元素进行比较,若前面大于后面的,则交换;依此循环。

public static void selectSort(int[]a){
int len = a.length;
for(int i = 0; i<len;i++){
for(int j = i+1;j<len;j++){
if(a[i]>a[j]){
swap(a, i, j);
}
System.out.print("i = " +i+", j = "+j+"    ");
print(a);
}
}
}


选择排序优化思路和冒泡不一样。冒泡能如此优化是因为每轮循环后,都能知道数组的局部排序情况,而选择不行。

选择排序可以减少交换次数,每轮循环结束后再进行交换。网上很多,这里不说了。若有更好的优化方法,请告知。


  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值