最近读《算法》,这本书把插入排序,选择排序两种排序方法的优缺点,适用场合,效率分析的非常透彻,文章标题的冒泡算法是我自己加进去的,下面我们会以java代码来比较三种算法。
1.选择排序
选择排序的基本思想是从数组中找出最大/最小的那个元素,把它和数组第一的元素交换,然后在下一轮中找出剩余数组中最大/最小的元素,把它和数组第二个元素交换,依次类推。
- package sort;
- import java.util.Arrays;
- /**
- * Created by 灵魂都在冒香气的神 on 2018/2/24.
- * 升序排序
- */
- public class SelectSort
- {
- public static void sort(int[] a)
- {
- int min_index=0,tmp;
- for (int i=0;i<a.length;i++)
- {
- min_index=i;
- for (int j=i+1;j<a.length-1;j++)
- {
- if (a[min_index]>a[j])
- {
- min_index=j;
- }
- }
- Util.exchange(a,min_index,i);
- }
- }
- public static void main(String[] args)
- {
- int[] num=Util.random(100);
- SelectSort.sort(num);
- Util.print(num);
- }
- }
2.插入排序
插入排序是指在一个有序序列中不断插入元素,使这个序列维持有序的状态,讲的不是很好,还是直接看代码吧
- package sort;
- /**
- * Created by 灵魂都在冒香气的神 on 2018/2/24.
- */
- public class InsertSort
- {
- public static void sort(int[] a)
- {
- for (int i=0;i<a.length;i++)
- {
- for (int j=i;j>0&&a[j]<a[j-1];j--)
- {
- Util.exchange(a,j-1,j);
- }
- }
- }
- }
3.冒泡排序
冒泡排序可能是最简单的一种排序算法,可能每个教C语言的老师都会给学生讲这种算法吧,但是,经过测试,冒泡算法是三种算法中效率最低的。
- package sort;
- /**
- * Created by 灵魂都在冒香气的神 on 2018/2/24.
- */
- public class BubbleSort
- {
- public static void sort(int[] a)
- {
- for (int i=0;i<a.length;i++)
- {
- for (int j=0;j<a.length-i-1;j++)
- {
- if (a[j]>a[j+1])
- {
- Util.exchange(a,j,j+1);
- }
- }
- }
- }
- }
4.开始测试
我们先写一个工具类,里面有两个方法:random()和exchange(),分别用产生随机数组和交换数组的两个元素。
- package sort;
- import java.util.Random;
- /**
- * Created by 灵魂都在冒香气的神 on 2018/2/24.
- */
- public class Util
- {
- public static void exchange(int[] a,int x,int y)
- {
- int tmp=a[x];a[x]=a[y];a[y]=tmp;
- }
- public static int[] random(int count)
- {
- Random raner=new Random();
- int[] num=new int[count];
- for (int i=0;i<count;i++)
- {
- num[i]=raner.nextInt(count);
- }
- return num;
- }
- public static void print(int[] a)
- {
- for (int i=0;i<a.length;i++)
- {
- System.out.println(a[i]);
- }
- }
- }
然后是测试类Test,测试处理十万个数据三种算法所需要的时间。
- package sort;
- /**
- * Created by 灵魂都在冒香气的神 on 2018/2/24.
- */
- public class Test
- {
- public static void main(String[] args)
- {
- int[] num=Util.random(1000*100); //产生10万个随机数
- /*复制数组副本*/
- int[] a=num.clone();
- int[] b=num.clone();
- int[] c=num.clone();
- long start=System.currentTimeMillis();
- InsertSort.sort(a);
- long end=System.currentTimeMillis();
- System.out.println("插入排序耗时:"+(end-start)/1000.0);
- start=System.currentTimeMillis();
- BubbleSort.sort(b);
- end=System.currentTimeMillis();
- System.out.println("冒泡排序耗时:"+(end-start)/1000.0);
- start=System.currentTimeMillis();
- SelectSort.sort(c);
- end=System.currentTimeMillis();
- System.out.println("选择排序耗时:"+(end-start)/1000.0);
- }
- }
运行结果截图:
测试看出,在十万个随机数下,冒泡排序效率是最低的,插入排序效率最高。
5.结果分析
虽然三者的时间复杂度均为O(n^2),但是三种算法的最好情况和最查情况是不一样的。在大量随机随机数下,随机序列越混乱,冒泡排序的效率就越低。序列越有序,插入排序的比较次数,交换次数就越少,最坏情况下约需要N^2/2次比较和N次数据交换,而选择排序的比较,交换次数和输入数据的混乱程度无关,大约需要N^2/2次比较和N次数据交换,与冒泡不同的是,虽然冒泡排序的排序次数也是大约N^2/2,但是,冒泡排序的数据交换次数是不确定的,和数据的混乱程度成正相关。所以,我们可以得出,不管数据有多混乱,或者数据相对有序,插入排序的效率>选择排序的效率>冒泡排序的效率。
以上是作者的拙见,作者还是大二学生,若是文章中出现错误,虚心接收意见。