常见算法插入、归并、冒泡和快速排序,对于数据量较大排序,顾名思义,快速排序最佳啦。
很多人包括我,只知道快速排序很快,但是它有什么特殊之处,算法是怎么实现,以及真正程序在运行时消耗时间是多少,和其它算法比,差多少呢?
我用JAVA语言简单实现了上述几种算法,小弟经验尚浅,纯碎只是玩玩而已,在算法逻辑不是最佳,然后用5w个整型数组分别对各算法测试,运行结果如下:
冒泡排序消耗时间:
运行时间:9464 毫秒
运行时间:9473 毫秒
运行时间:9075 毫秒
运行时间:9041 毫秒
运行时间:9108 毫秒
运行时间:9042 毫秒
运行时间:8989 毫秒
运行时间:9063 毫秒
运行时间:9085 毫秒
运行时间:9128 毫秒
插入排序消耗时间:
运行时间:4339 毫秒
运行时间:4286 毫秒
运行时间:4069 毫秒
运行时间:4068 毫秒
运行时间:4075 毫秒
运行时间:4060 毫秒
运行时间:4086 毫秒
运行时间:4064 毫秒
运行时间:4051 毫秒
运行时间:4071 毫秒
归并排序消耗时间:
运行时间:20 毫秒
运行时间:17 毫秒
运行时间:16 毫秒
运行时间:17 毫秒
运行时间:16 毫秒
运行时间:17 毫秒
运行时间:16 毫秒
运行时间:16 毫秒
运行时间:16 毫秒
运行时间:16 毫秒
快速排序消耗时间:
运行时间:14 毫秒
运行时间:9 毫秒
运行时间:8 毫秒
运行时间:9 毫秒
运行时间:9 毫秒
运行时间:9 毫秒
运行时间:8 毫秒
运行时间:8 毫秒
运行时间:9 毫秒
运行时间:9 毫秒
时间消耗:快速<归并<插入<冒泡
5w数据量,快速排序的速度是冒泡的900倍,真是快,真不是浪得虚名。
最后按惯例附上代码,留着纪念。。
import java.util.ArrayList;
import java.util.Collections;
public class Test {
/**
* 插入排序
* 从数组的第二个元素开始循环,将选中的元素与之前的元素一一比较,
* 如果选中的元素小于之前的元素,将之前的元素后移,最后选中的元素放到合适的位置。
* @param args
*/
public static void insertSort(int[] ints){
for (int i = 1; ints.length > 1 && i < ints.length; i++) {
for (int j = 0; j < i; j++) {
if(ints[i] < ints[j]){
int tmp = ints[i];
ints[i] = ints[j];
ints[j] = tmp;
}
}
}
}
/**
* 归并排序
* 将数组拆分成较小的数组,排序后再合并。数组长度不大于1,不再拆分。
* @param ints
*/
public static void guibingSort(int[] ints){
away(ints,0,ints.length);
}
/**
* 拆分长度大于1数组
* @param ints
* @param pos
* @param end
*/
public static void away(int[] ints,int pos,int end){
if(end - pos > 1){
int mid = (pos + end)/2;
away(ints,pos,mid);
away(ints,mid,end);
merge(ints,pos,mid,end);
}
}
/**
* 合并数组
* @param ints
* @param pos
* @param mid
* @param end
*/
public static void merge(int[] ints,int pos,int mid,int end){
int[] array1 = new int[mid-pos];
int[] array2 = new int[end-mid];
System.arraycopy(ints, pos, array1, 0, array1.length);
System.arraycopy(ints, mid, array2, 0, array2.length);
for (int i = pos,j=0,k=0; i < end; i++) {
if(j==array1.length){
System.arraycopy(array2, k, ints, i, array2.length - k);
break;
}
if(k==array2.length){
System.arraycopy(array1, j, ints, i, array1.length - j);
break;
}
if(array1[j]<array2[k]){
ints[i] = array1[j++];
}else{
ints[i] = array2[k++];
}
}
}
/**
* 冒泡排序
* 算法循环n-1次,在未排好序的区域中从后往前比较相邻两个元素,大数在后,小数在前。
* @param ints
*/
public static void bubbleSort(int[] ints){
for (int i = 0; i < ints.length -1; i++) {
for (int j = ints.length -1; j >i; j--) {
if(ints[j-1]>ints[j]){
int tmp = ints[j-1];
ints[j-1] = ints[j];
ints[j] = tmp;
}
}
}
}
/**
* 快速排序
* 利用分治的思想,将大问题拆分成若干相似的子问题,递归解决这些子问题,然后将这些子问题的解组合成原问题。
* @param ints
*/
public static void quickSort(int[] ints){
recursive(ints,0,ints.length);
}
public static void recursive(int[] ints, int pos, int end){
if(end - pos > 1){
int index = partion(ints, pos, end);
recursive(ints, pos, index);
recursive(ints, index+1 , end);
}
}
public static int partion(int[] ints, int pos, int end){
//取数组最后一个元素作为参考值
int indexValue = ints[end-1];
int index = pos;
for (int i = pos, j = pos; i < end - 1; i++) {
if(ints[i] < indexValue ){
if(i>j){
int tmp = ints[i];
ints[i] = ints[j];
ints[j] = tmp;
}
j++;
index = j;
}
}
ints[end-1] = ints[index];
ints[index] = indexValue;
return index;
}
private static final int count = 50000;
public static void main(String[] args) {
//构造无序列表
ArrayList list = new ArrayList();
for (int i = 0; i < count; i++) {
list.add(i);
}
Collections.shuffle(list);
int[] outOfOrderInts = new int[count];
for (int i = 0; i < outOfOrderInts.length; i++) {
outOfOrderInts[i] = (int) list.get(i);
}
int[] ints = null;
System.out.println("冒泡排序消耗时间:");
for (int i = 0; i < 10; i++) {
ints = outOfOrderInts.clone();
testBubbleSortUseTime(ints);
}
System.out.println("插入排序消耗时间:");
for (int i = 0; i < 10; i++) {
ints = outOfOrderInts.clone();
testInsertSortUseTime(ints);
}
System.out.println("归并排序消耗时间:");
for (int i = 0; i < 10; i++) {
ints = outOfOrderInts.clone();
testGuibingSortUseTime(ints);
}
System.out.println("快速排序消耗时间:");
for(int i = 0; i < 10; i++){
ints = outOfOrderInts.clone();
testQuickSortUseTime(ints);
}
}
public static void testGuibingSortUseTime(int[] ints){
long now = System.currentTimeMillis();
guibingSort(ints);
long end = System.currentTimeMillis() - now;
System.out.println("运行时间:" + end + " 毫秒");
}
public static void testBubbleSortUseTime(int[] ints){
long now = System.currentTimeMillis();
bubbleSort(ints);
long end = System.currentTimeMillis() - now;
System.out.println("运行时间:" + end + " 毫秒");
}
public static void testInsertSortUseTime(int[] ints){
long now = System.currentTimeMillis();
insertSort(ints);
long end = System.currentTimeMillis() - now;
System.out.println("运行时间:" + end + " 毫秒");
}
public static void testQuickSortUseTime(int[] ints){
long now = System.currentTimeMillis();
quickSort(ints);
long end = System.currentTimeMillis() - now;
System.out.println("运行时间:" + end + " 毫秒");
}
}