前几天在《程序员》上看到一个人的博客上有用java实现的所有的排序算法,在这里,我想我也做过,我也放上来,供大家对比,相互学习和交流。
测试类:
package Sort;
public class Test {
public Test() {
}
// 产生测试数据
public static Data[] getData(int size){
Data[] data=new Data[size+1];
int number;
for(int i=0;i<data.length;i++){
number=(int) (Math.random() * size*10);
data[i] = new Data(new Integer(number),new Integer(number));
}
return data;
}
// 复制测试数据
public static Data[] duplicationData(Data[] data){
Data[] duplication=new Data[data.length];
for(int i=1;i<data.length;i++){
duplication[i]=new Data(data[i]);
}
return duplication;
}
public static void printData(Data[] data){
for(int i=1;i<data.length;i++)
System.out.print(data[i].toString());
}
public static void main(String[] args) {
long startTime,stopTime,sortingTime;
Data[] data=getData(6000);
Data[] data1,data2,data3,data4,data5,data6,data7,data8,data9,data10;
data1=duplicationData(data);
data2=duplicationData(data);
data3=duplicationData(data);
data4=duplicationData(data);
data5=duplicationData(data);
data6=duplicationData(data);
data7=duplicationData(data);
data8=duplicationData(data);
data9=duplicationData(data);
data10=duplicationData(data);
startTime= System.currentTimeMillis();
Sort.InsertionSort.straightInsertionSort(data1);
stopTime= System.currentTimeMillis();
sortingTime=stopTime-startTime;
System.out.println("Straight Insertion Sort time is "+ sortingTime);
//System.out.println("Straight Insertion Sort Answer");
//printData(data1);
startTime= System.currentTimeMillis();
Sort.InsertionSort.BinaryInsertionSort(data2);
stopTime= System.currentTimeMillis();
sortingTime=stopTime-startTime;
System.out.println("Binary Insertion Sort time is "+ sortingTime);
//System.out.println("Binary Insertion Sort Answer");
//printData(data2);
startTime= System.currentTimeMillis();
Sort.InsertionSort.ListInsertionSort(data3);
stopTime= System.currentTimeMillis();
sortingTime=stopTime-startTime;
System.out.println("List Insertion Sort time is "+ sortingTime);
//System.out.println("List Insertion Sort Answer");
//printData(data3);
startTime= System.currentTimeMillis();
Sort.QuickSort.BubbleSort(data4);
stopTime= System.currentTimeMillis();
sortingTime=stopTime-startTime;
System.out.println("Bubble Sort time is "+ sortingTime);
//System.out.println("Bubble Sort Answer");
//printData(data4);
startTime= System.currentTimeMillis();
Sort.QuickSort.QuickSort(data5);
stopTime= System.currentTimeMillis();
sortingTime=stopTime-startTime;
System.out.println("Quick Sort time is "+ sortingTime);
//System.out.println("Quick Sort Answer");
//printData(data5);
startTime= System.currentTimeMillis();
Sort.QuickSort.SimpleSelectSort(data6);
stopTime= System.currentTimeMillis();
sortingTime=stopTime-startTime;
System.out.println("Select Sort time is "+ sortingTime);
//System.out.println("Select Sort Answer");
//printData(data6);
startTime= System.currentTimeMillis();
Sort.QuickSort.MergingSort(data7);
stopTime= System.currentTimeMillis();
sortingTime=stopTime-startTime;
System.out.println("Merging Sort time is "+ sortingTime);
//System.out.println("Merging Sort Answer");
//printData(data7);
startTime= System.currentTimeMillis();
Sort.QuickSort.RadixSort(data8,5);
stopTime= System.currentTimeMillis();
sortingTime=stopTime-startTime;
System.out.println("Radix Sort time is "+ sortingTime);
//System.out.println("Radix Sort Answer");
//printData(data8);
startTime= System.currentTimeMillis();
Sort.QuickSort.HeapSort(data);
stopTime= System.currentTimeMillis();
sortingTime=stopTime-startTime;
//System.out.println("Heap Sort time is "+ sortingTime);
//System.out.println("Radix Sort Answer");
//printData(data9);
startTime= System.currentTimeMillis();
Sort.QuickSort.OptimizeQuickSort(data10);
stopTime= System.currentTimeMillis();
sortingTime=stopTime-startTime;
System.out.println("Optimize Quick Sort time is "+ sortingTime);
//System.out.println("Optimize Quick Sort Answer");
//printData(data10);
}
}
测试结果:
各种排序的测试数据表:
| 100 | 500 | 1000 | 10000 | ||||||||||
直接插入排序 | 0 | 10 | 20 | 1752 | ||||||||||
二分插入排序 | 0 | 10 | 10 | 551 | ||||||||||
表插入排序 | 10 | 10 | 30 | 2153 | ||||||||||
起泡排序 | 10 | 30 | 50 | 5068 | ||||||||||
快排 | 0 | 0 | 10 | 20 | ||||||||||
简单选择排序 | 30 | 20 | 20 | 3535 | ||||||||||
归并排序 | 0 | 0 | 60 | 190 | ||||||||||
基数排序 | 20 | 20 | 110 | 140 | ||||||||||
堆排序 | 0 | 0 | 0 | 10 |
|
|
|
|
|
|
|
|
|
|
关于快排:
快速排序的运行时间与划分是否对称有关,最糟的情况是每次划分时一边是一个元素,一边是 n-1 个,这种情况的时间复杂度是
在最好的情况是,每次划分的枢轴都是中值,此时的时间复杂度是 ,在一些书上提到快速排序在平均情况下的复杂度也是 ,所以可以提出一个处理恶化的方法,在排序算法的每一步,可以随机选取一个元素关键字作为枢轴,这样总体来说平均划分是对称的。
可以把取枢轴的算法改一下:
int RandomizedPartition(DataType[] a , int p , int r){
int i= Random(p , r);
Swap(a[i] ,a[p]);
return Partition(a,p,r);
}
| 500 | 1000 | 10000 | 100000 | 200000 |
普通快排 | 10 | 10 | 40 | 501 | 1181 |
优化快排 | 0 | 0 | 10 | 430 | 1142 |
可以看出,优化后的快排明显的提高了排序的速度,但是同时也可以看出,当元素很多时,交换的次数也增多了,使得优化后的排序的优势不很明显了,这是因为被排的数据是随机的。
下面显示的是这两种快排对有序的处理时间 ( 数据 >7000 ,内存溢出 ) :
| 100 | 500 | 1000 | 3000 | 6000 |
普通快排 | 10 | 10 | 80 | 250 | 991 |
优化快排 | 0 | 40 | 20 | 160 | 731 |
由此可知,优化快排能缓解恶化。