实验冒泡、选择、插入排序算法的效率问题
引出问题:关于三个简单排序的效率问题,之前在网上看到关于冒泡、选择、插入的效率问题。
首先冒泡效率时最低的,但对于选择和插入排序的效率问题有的说插入略高;有的说选择略高。
于是我自己验证了一把。
大致过程思路:测试80000个随即元素的素组,分别采用三种排序算法进行排序 获取排序前后的两个时间点计算其消耗时间,时间差越短 则效率越高
冒泡排序:
- 思想:把相邻两个元素进行比较,把较大的交换到右边(从小到大)
- 图解:
- 代码实现
package com.mzll.algorithm.sort;
import java.util.Arrays;
public class SelectSort {
public static void main(String[] args) {
int[] arr = new int[80000];
int[] arrx = {1,3,6,5,2,8,9,7};
for (int i = 0; i < arr.length; i++) {
arr[i] = (int)(Math.random()*100000);
}
long millis = System.currentTimeMillis();
insertSort(arr);
long millis1 = System.currentTimeMillis();
System.out.println(Arrays.toString(arr));
System.out.println("冒泡排序80000个数据耗时"+(millis1 - millis) + "毫秒");
}
/**
* 冒泡排序思想 相邻的两个元素比较把较大的换至右边
* @param arr
* 80000个数据8秒
*/
public static void bubbleSort(int[] arr) {
int temp;
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length - i - 1; j++) {
if(arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
//System.out.println(Arrays.toString(arr));
}
}
}
- 运行结果如下:
选择排序(直接选择):
-
思想:从数组的第二个元素开始往后查找,找到最小的与第一个交换 再找到第二小的与第二个交换以此类推
-
第一次从R[0]R[n-1]中选取最小值,与R[0]交换,第二次从R1R[n-1]中选取最小值,与R1交换,….,第i次从R[i-1]R[n-1]中选取最小值,与R[i-1]交换,……,第n-1次从R[n-2]R[n-1]中选取最小值,与R[n-2]交换,总共通过n-1次,得到一个按排序码从小到大排列的有序序列。直接选择排序是一种不稳定的排序算法
-
图解:
-
代码实现
package com.mzll.algorithm.sort;
import java.util.Arrays;
public class SelectSort {
public static void main(String[] args) {
int[] arr = new int[80000];
int[] arrx = {1,3,6,5,2,8,9,7};
for (int i = 0; i < arr.length; i++) {
arr[i] = (int)(Math.random()*100000);
}
long millis = System.currentTimeMillis();
//insertSort(arr);
//select(arr);
bubbleSort(arr);
long millis1 = System.currentTimeMillis();
System.out.println(Arrays.toString(arr));
System.out.println("选择排序80000个数据耗时"+(millis1 - millis) + "毫秒");
}
/**
* 选择排序思想:从数组的第二个元素开始往后查找,找到最小的与第一个交换 再找到第二小的与第二个交换以此类推
* 80000个数据0.6秒左右
* @author mzll
*
*/
public static void select(int[] arr) {
int index ;
int min;
int temp;
for (int j = 0; j < arr.length; j++) {
index = j;
min = arr[index];
for (int i = j + 1; i < arr.length; i++) {
if (min > arr[i]) {
index = i;
min = arr[index];
}
}
temp = arr[j];
arr[j] = arr[index];
arr[index] = temp;
}
}
}
- 运行结果:
插入排序(直接插入):
- 思想:每步将一个待排序元素,按其排序码大小插入到前面已经排好序的一组元素中,直到元素全部插入为止。在这里,我们介绍三种具体的插入排序算法
- 图解:
package com.mzll.algorithm.sort;
import java.util.Arrays;
public class SelectSort {
public static void main(String[] args) {
int[] arr = new int[80000];
int[] arrx = {1,3,6,5,2,8,9,7};
for (int i = 0; i < arr.length; i++) {
arr[i] = (int)(Math.random()*100000);
}
long millis = System.currentTimeMillis();
//insertSort(arr);
select(arr);
//bubbleSort(arr);
long millis1 = System.currentTimeMillis();
System.out.println(Arrays.toString(arr));
System.out.println("插入排序80000个数据耗时"+(millis1 - millis) + "毫秒");
}
/**
* 插入排序思想:把数组的前一部分看作一个有序列表 把后一部分看作一个无序列表
* 每次去除无序列表的第一个元素插入到有序列表的合适的位置
* @param arr
*/
public static void insertSort(int[] arr) {
int insertIndex = 0;
int insertVal = 0;
for (int i = 1; i < arr.length; i++) {
insertIndex = i-1;//待插入元素的前一个元素的索引
insertVal = arr[i];//待插入数据
while(insertIndex >= 0 && insertVal < arr[insertIndex]) {
arr[insertIndex + 1] = arr[insertIndex];
insertIndex --;
}
arr[insertIndex + 1] = insertVal;
//System.out.println(Arrays.toString(arr));
}
}
}
- 运行结果:
结论:冒泡排序效率最低,选择排序高于插入排序。
补充:像这种实验要多测几次(至少三次以上)取其平均值才具有代表性,我在下面测了多次,以上图片选取了最具代表性的几张,足以说明问题,
后续会持续更新关于算法效率,和设计模式的帖子。