排序之冒泡排序,插入排序,选择排序

最近读《算法》,这本书把插入排序,选择排序两种排序方法的优缺点,适用场合,效率分析的非常透彻,文章标题的冒泡算法是我自己加进去的,下面我们会以java代码来比较三种算法。

1.选择排序

选择排序的基本思想是从数组中找出最大/最小的那个元素,把它和数组第一的元素交换,然后在下一轮中找出剩余数组中最大/最小的元素,把它和数组第二个元素交换,依次类推。

[java]  view plain  copy
  1. package sort;  
  2.   
  3. import java.util.Arrays;  
  4.   
  5. /** 
  6.  * Created by 灵魂都在冒香气的神 on 2018/2/24. 
  7.  * 升序排序 
  8.  */  
  9. public class SelectSort  
  10. {  
  11.     public static void sort(int[] a)  
  12.     {  
  13.         int min_index=0,tmp;  
  14.         for (int i=0;i<a.length;i++)  
  15.         {  
  16.             min_index=i;  
  17.             for (int j=i+1;j<a.length-1;j++)  
  18.             {  
  19.                 if (a[min_index]>a[j])  
  20.                 {  
  21.                     min_index=j;  
  22.                 }  
  23.             }  
  24.             Util.exchange(a,min_index,i);  
  25.         }  
  26.     }  
  27.   
  28.     public static void main(String[] args)  
  29.     {  
  30.         int[] num=Util.random(100);  
  31.         SelectSort.sort(num);  
  32.         Util.print(num);  
  33.     }  
  34. }  

2.插入排序

插入排序是指在一个有序序列中不断插入元素,使这个序列维持有序的状态,讲的不是很好,还是直接看代码吧

[java]  view plain  copy
  1. package sort;  
  2.   
  3. /** 
  4.  * Created by 灵魂都在冒香气的神 on 2018/2/24. 
  5.  */  
  6. public class InsertSort  
  7. {  
  8.     public static void sort(int[] a)  
  9.     {  
  10.         for (int i=0;i<a.length;i++)  
  11.         {  
  12.             for (int j=i;j>0&&a[j]<a[j-1];j--)  
  13.             {  
  14.   
  15.                 Util.exchange(a,j-1,j);  
  16.             }  
  17.         }  
  18.     }  
  19. }  

3.冒泡排序

      冒泡排序可能是最简单的一种排序算法,可能每个教C语言的老师都会给学生讲这种算法吧,但是,经过测试,冒泡算法是三种算法中效率最低的。

它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越大的元素会经由交换慢慢“浮”到数列的顶端。
[java]  view plain  copy
  1. package sort;  
  2.   
  3. /** 
  4.  * Created by 灵魂都在冒香气的神 on 2018/2/24. 
  5.  */  
  6. public class BubbleSort  
  7. {  
  8.     public static void sort(int[] a)  
  9.     {  
  10.         for (int i=0;i<a.length;i++)  
  11.         {  
  12.             for (int j=0;j<a.length-i-1;j++)  
  13.             {  
  14.                 if (a[j]>a[j+1])  
  15.                 {  
  16.                     Util.exchange(a,j,j+1);  
  17.                 }  
  18.             }  
  19.         }  
  20.     }  
  21. }  

4.开始测试

我们先写一个工具类,里面有两个方法:random()和exchange(),分别用产生随机数组和交换数组的两个元素。

[java]  view plain  copy
  1. package sort;  
  2.   
  3. import java.util.Random;  
  4.   
  5. /** 
  6.  * Created by 灵魂都在冒香气的神 on 2018/2/24. 
  7.  */  
  8. public class Util  
  9. {  
  10.     public static void exchange(int[] a,int x,int y)  
  11.     {  
  12.         int tmp=a[x];a[x]=a[y];a[y]=tmp;  
  13.     }  
  14.   
  15.     public static int[] random(int count)  
  16.     {  
  17.         Random raner=new Random();  
  18.         int[] num=new int[count];  
  19.         for (int i=0;i<count;i++)  
  20.         {  
  21.             num[i]=raner.nextInt(count);  
  22.         }  
  23.         return num;  
  24.     }  
  25.     public static void print(int[] a)  
  26.     {  
  27.         for (int i=0;i<a.length;i++)  
  28.         {  
  29.             System.out.println(a[i]);  
  30.         }  
  31.     }  
  32. }  

然后是测试类Test,测试处理十万个数据三种算法所需要的时间。

[java]  view plain  copy
  1. package sort;  
  2.   
  3. /** 
  4.  * Created by 灵魂都在冒香气的神 on 2018/2/24. 
  5.  */  
  6. public class Test  
  7. {  
  8.     public static void main(String[] args)  
  9.     {  
  10.   
  11.         int[] num=Util.random(1000*100);  //产生10万个随机数  
  12.         /*复制数组副本*/  
  13.         int[] a=num.clone();  
  14.         int[] b=num.clone();  
  15.         int[] c=num.clone();  
  16.   
  17.   
  18.         long start=System.currentTimeMillis();  
  19.         InsertSort.sort(a);  
  20.         long end=System.currentTimeMillis();  
  21.         System.out.println("插入排序耗时:"+(end-start)/1000.0);  
  22.   
  23.   
  24.         start=System.currentTimeMillis();  
  25.         BubbleSort.sort(b);  
  26.         end=System.currentTimeMillis();  
  27.         System.out.println("冒泡排序耗时:"+(end-start)/1000.0);  
  28.   
  29.           
  30.         start=System.currentTimeMillis();  
  31.         SelectSort.sort(c);  
  32.         end=System.currentTimeMillis();  
  33.         System.out.println("选择排序耗时:"+(end-start)/1000.0);  
  34.     }  
  35. }  

运行结果截图:

测试看出,在十万个随机数下,冒泡排序效率是最低的,插入排序效率最高。

5.结果分析

虽然三者的时间复杂度均为O(n^2),但是三种算法的最好情况和最查情况是不一样的。在大量随机随机数下,随机序列越混乱,冒泡排序的效率就越低。序列越有序,插入排序的比较次数,交换次数就越少,最坏情况下约需要N^2/2次比较和N次数据交换,而选择排序的比较,交换次数和输入数据的混乱程度无关,大约需要N^2/2次比较和N次数据交换,与冒泡不同的是,虽然冒泡排序的排序次数也是大约N^2/2,但是,冒泡排序的数据交换次数是不确定的,和数据的混乱程度成正相关。所以,我们可以得出,不管数据有多混乱,或者数据相对有序,插入排序的效率>选择排序的效率>冒泡排序的效率。


以上是作者的拙见,作者还是大二学生,若是文章中出现错误,虚心接收意见。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值