冒泡排序法和选择排序法

一、冒泡排序法

1、算法分析:
     5个数 3  1  6  2  5 从小到大排序输出
int[] a = {3,1,6,2,5};
从第一个数开始,a[0]跟a[1]比,a[1]跟a[2]比,a[2]跟a[3]比,a[3]跟a[4]比,然后先直接
选出一个最大的数排在最右边,即5个数中最大的在最右边,这样的冒泡排序要比4次;
再然后前面的4个数再按这样的方法进行排序,选出前面4个数中最大的排在右边倒数第二位置,
这样的冒泡排序要比3次。
依次类推,最终冒泡比较的次数是:
 4 
 3
 2
 1
最终排成:1  2  3  5  6
即满足两个要求:(1) a[0]跟a[1]比,a[1]跟a[2]比,a[2]跟a[3]比,a[3]跟a[4]比
                (2) 两个元素相比,如果左边大于右边,则交换位置,不大,则不换

数组中两个前后元素交换数据:
int temp = a[i]; a[i] = a[i+1]; a[i+1] = temp;

我们先来看看,在一行数中选出最大的数,排在最右边,如 3  1  6  2  5 
for(i=0;i<5;i++){
   if(a[i]>a[i+1]){
     int temp = a[i];
     a[i] = a[i+1];
     a[i+1] = temp;
   }
}
显然,当出现a[4]>a[4+1],这是不可能的,所以i的范围大了,应该是i<4
  
2、测试:
2.1、
// 5中选最大
public class day4{
  public static void main(String[] args){
        
   //静态初始化
   int[] a = {8,1,6,2,5};
   for(int i=0;i<4;i++){
     if(a[i]>a[i+1]){
     int temp = a[i];
     a[i] = a[i+1];
     a[i+1] = temp;
     }
   }
   System.out.println(a[4]);
 }
}
输出:8

2.2、
以上只是在5个数中比较4次,选出最大的数排在最右边 8
然后,再在剩下的4个数中比较4此,选出最大的数排在最右边 6
剩下4中选最大
public class day4{
  public static void main(String[] args){
        
    //静态初始化
    int[] a = {1,6,2,5};
    for(int i=0;i<3;i++){
      if(a[i]>a[i+1]){
int temp = a[i];
a[i] = a[i+1];
a[i+1] = temp;
}
      }
      System.out.println(a[3]);
    }
}
//选出了最大的数6排在最右边,比较3次,经过前两轮的比较,最右边排的是 6 8
输出:6

2.3、
由此类推,依次在剩下的3个,2个中选出最大的数,
将这些集合起来:
public class day4{
  public static void main(String[] args){
    int[] a = {8,1,6,2,5};

    for(int i=0;i<5;i++){
      for(int j=0;j<4-i;j++){
if(a[j]>a[j+1]){
 int temp = a[j];
 a[j] = a[j+1];
 a[j+1] = temp;
}
      }
    }

    for(int i=0;i<5;i++){
      System.out.print(a[i] + " ");
    }
  }
}
输出: 1 2 5 6 8

2.4、
总结,冒泡排序法,满足两个要求:
(1) a[0]跟a[1]比,a[1]跟a[2]比,a[2]跟a[3]比,a[3]跟a[4]比
(2) 两个元素相比,如果左边大于右边,则交换位置,不大,则不换

1.确定比较的次数,分别的次数为4 3 2 1 
2.确定a[i]和a[i+1]的大小,怎么交换,肯定有if判断:
 if(a[j]>a[j+1]){
   int temp = a[j];
   a[j] = a[j+1];
   a[j+1] = temp;
 }
3.确定在每个比较的次数中,参与比较大小的元素。比如要比较4次,参与了比较的元素有:
   a[0],a[1],a[2],a[3],a[4]
   要比较3次,参与了比较的元素有:
   a[0],a[1],a[2],a[3]
4.将每次比较的最大数从左至右排好:
for(int i=0;i<5;i++){
  System.out.print(a[i] + " ");

}

3、怎么做呢?

(1)比如 int[] a = {8,1,6,2,5}; 我们最终要排成:int[] a = {1,2,5,6,8};
(2)先把8排出来,排出最大的数在右边
for(int j=0;j<4;j++){
  if(a[j]>a[j+1]){
    int temp = a[j];
    a[j] = a[j+1];
    a[j+1] = temp;
  }
}
(3)在(2)中,这样比较了4次,得出8;再接着比较3次,得出6;接着比较2次,得出5;比较
   2次,得出2.
这样每回比较得到最大的数的时候,那个for循环代码不变,
然无非外面再套个for循环,来循环比较的回数:4,3,2,1
for(int i=0;i<5;i++){
}
 
冒泡排序法的特点是:先在几个数中选出最大的,然后把这个最大的拿走,在剩下的几个数中再选
出最大,再拿走,依次这样选。最后,将所有选出的最大的左到右排出来。

4、大神的思路:
冒泡排序法思路

1:外层循环:控制它要走几次。 
假设你有5个数,那就要走4次,最后一次不用走,最后那个数已经在它位置了所以就要length-1次。
2:内层循环:控制逐一比较,如果发现前一个数比后一个数大,则交换。 
注意!因为越比较长度就越小了,所以长度要length-1-i。

//外层循环,它决定一共走几趟
for(int i = 0;i<a.length-1;i++){
  //内层循环,开始逐个比较
  //如果我们发现前一个数比后一个数大,则交换
  for(int j=0;j<a.length-1-i;j++){
    if(arr[j]>a[j+1]){
      //换位
      temp = a[j];
      a[j] = a[j+1];
      a[j+1] = temp;
    }
  }
}


二、选择排序法

1、概念: 
第一次从R[0]~R[n-1]中选取最小值,与R[0]交换。第二次从R[1]~R[n-1]中选取最小值与R[1]交换,
以此类推。 
通俗点说就是每次找到后面元素的最小值然后与之交换。 
选择排序法效率中。 

如: 8 3  2  1
第一次,从8开始,找到最小值1,与8交换,为 1 3 2 8
第二次,从3开始往后比较,找到最小值2,与3交换,为 1 2 3 8
第三次,从3开始往后比较,找到最小值3,不用交换,为 1 2 3 8
总共要进行4次。

2、选择排序思路 
 1:外层循环:要走几趟,同样是length-1。 
 2:设置一个最小值。假设第一个就是最小值。 
 3:设置一个最小值下标,min
 4:内层循环:那你当前的最小值去逐一比较。当有比当前最小值小的数时,记录最小值,记录下标。 
 5:退出内层循环后就交换位置。

public class day4{
  public static void main(String[] args){
    int[] a = {8,1,6,2,5};

    //外循环:我认为最小的数,从0~长度-1
    for(int i=0;i<a.length-1;i++){
    //最小数,假设第一个数就是最小的
    int min = i;  //这里假设的第一个就是a[0],min和i表示的都是下标数

    //内循环:拿出我认为最小的数和它后面的数一一进行比较
    for(int j=i+1;j<a.length;j++){
      //找到最小值下标
      if(a[j]<a[min]){
      min=j; //交换下标,意味着后面加上a[min]和a[j],交换内存地址了
      }
    }

    //当退出内循环时,就表示找到了这次的最小值,然后与原先假设的最小值交换
    //交换
    if(min!=i){
      int temp = a[i];
      a[i] = a[min];
      a[min] = temp;
    }
   }

   for(int i=0;i<a.length;i++){
     System.out.print(a[i] + " ");
   }
  }
}
输出: 1 2 5 6 8

3、分析,冒泡排序和选择排序:
   1.都是先确定它们各自的算法思路
   2.然后都是外循环  内循环+交换
     外循环负责控制要走几趟
     内循环负责每一趟的比较,然后进行交换
   3.最后,再重写从左至右排序打印出来。

4、比较一下两个排序法之间的效率差异:

import java.util.Calendar;
public class Demo{
  public static void main(String[] args){
    //构建一个庞大的无序数组用于测试时间
    int len=100000;
    int arr1 [] = new int [len];
    for(int i=0;i<len;i++){
       //让程序随机产生一个1~10000的数
       //Math.random()会产生一个0~1的数
       int t = (int)(Math.random()*10000);
       arr1[i] = t;
    }

    //简单测试数组
    int arr [ ] ={1,6,0,-1,9,1000,-1000,98,-687};
    //获得时间实例
    Calendar cal = Calendar.getInstance();
    //在排序前打印系统时间
    System.out.println("冒泡排序法开始"+cal.getTime());
    //调用冒泡排序法
    Bubble bubble = new Bubble();
    bubble.sort(arr1);
    //重新获得时间实例
    cal = Calendar.getInstance();
    System.out.println("冒泡排序法结束"+cal.getTime());

    //重新获得时间实例
    cal = Calendar.getInstance();
    System.out.println("选择排序法开始"+cal.getTime());
    //调用选择排序法
    Select select = new Select();
    select.sort(arr1);
    //重新获得时间实例
    cal = Calendar.getInstance();
    System.out.println("选择排序法结束"+cal.getTime());
  }
}

//-----------------冒泡排序法
class Bubble{
  //排序方法
  public void sort(int arr[]){
    int temp=0;//中间值
    //-------冒泡排序法
    //外层循环,它决定一共走几趟
    for(int i = 0;i<arr.length-1;i++){
       //内层循环,决定每一趟循环的次数
       //如果我们发现前一个数比后一个数大,则交换
         for(int j=0;j<arr.length-1-i;j++){
            if(arr[j]>arr[j+1]){
               //换位
               temp = arr[j];
               arr[j] = arr[j+1];
               arr[j+1] = temp;
            }
         }
    }   
    //输出结果
    for(int i = 0;i<arr.length;i++){
      System.out.print(arr[i]+" ");
    }
  }   
}

//--------------选择排序法
class Select{
  public void sort(int arr[]){
    //中间值
    int temp = 0;

    //外循环:我认为最小的数,从0~长度-1
    for(int j = 0; j<arr.length-1;j++){
       //最小值:假设第一个数就是最小的
       int min = arr[j];
       //记录最小数的下标的
       int minIndex=j;

       //内循环:拿我认为的最小的数和后面的数一个个进行比较找到下标
       for(int k=j+1;k<arr.length;k++){
          //找到最小值
          if(min>arr[k]){
            //修改最小
            min=arr[k];
            minIndex=k;
          }
       }
       //当退出内层循环就找到这次的最小值
       //交换位置
       temp = arr[j];
       arr[j]=arr[minIndex];
       arr[minIndex]=temp;
    }
    //输出结果
    for(int i = 0;i<arr.length;i++){
       System.out.print(arr[i]+" ");
    }
  }
}
选择排序法比冒泡排序法效率高,用时短。
  • 22
    点赞
  • 64
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值