归并排序
采用分而治之的策略,时间复杂度为N*log(N),是非常优秀的排序算法。
代码如下:
package com.time.before.test;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Random;
public class MegreSort2 {
public static Comparable[] aux ;
public static void sort(Comparable[] a){
aux = new Comparable[a.length];
sort(a, 0, a.length -1);
}
public static void sort(Comparable[] a, int low, int high){
if(low >= high) return;
int mid = low + (high - low) / 2 ;
sort(a, low, mid);
sort(a, mid + 1, high);
merge(a, low, mid, high);
}
public static void main(String[] args) throws FileNotFoundException{
buildData();
FileReader fr = new FileReader("D:\\data.txt");
BufferedReader br = new BufferedReader(fr);
try {
String line = br.readLine();
String[] datas = line.split(",");
Comparable[] a = new Comparable[datas.length];
for(int i = 0; i < datas.length; i++) a[i] = Integer.parseInt(datas[i]);
long t = System.currentTimeMillis();
MegreSort2.sort(a);
long sortTime = (System.currentTimeMillis() - t);
System.out.println(sortTime);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("D:\\sortData.txt"),"utf-8"));
int i = 0;
while(i < a.length){
bw.write(a[i] + ",");
i +=1;
}
bw.flush();
bw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// MegreSort2.sort(a);
// MegreSort2.buildData();
}
public static void merge(Comparable[] a, int low, int mid, int high){
int i = low, j = mid + 1;
// System.out.println(i + "\t" + mid + "\t" + high);
for(int k = low; k <= high; k ++) aux[k] = a [k];
for(int k = low; k <= high; k ++){
if(i > mid)
a[k] = aux[j ++];
else if(j > high)
a[k] = aux[i ++];
else if(less(aux[j], aux[i]))
a[k] = aux[j ++];
else
a[k] = aux[i ++];
}
}
public static boolean less(Comparable v, Comparable w){
return v.compareTo(w) < 0;
}
public static void buildData() throws FileNotFoundException{
try{
// FileWriter writer = new FileWriter("D:\\data.txt", true);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("D:\\data.txt"),"utf-8"));
// FileOutputStream fos = new FileOutputStream("D:\\data.txt", true);
int i = 0;
Random ra = new Random();
// System.out.println(ra.nextInt(1000000));
while(i <= 100000000){
bw.write(ra.nextInt(100000000) + ",");
i +=1;
}
bw.flush();
bw.close();
}catch(Exception e){
}
}
}
写完归并排序后,做了一个小测试,本机内存8G,随机生成1百万个整数,排序时间在1s左右,想进一步测试一亿个整数的排序时间,生成的数据文件大小为847m,出现了java堆溢出问题,设置java参数-Xms和-Xmx时,发现本地内存不够用(原因还未知),只好放弃
快速排序
快排的思想是随机在数组中选一个数,比如数组的第一个值,把该值放到正确的位置,保证该值左边的子数组都小于等于它,右边的子数组的值都大于等它。快排的时间复杂度为O(nlogn)。最换的情况为O(n2)。和归并排序的时间复杂度一样,但是少了新增一个数组内存的开销。
代码如下:
package com.time.before.test;
public class QuickSort {
public static void main(String[] args){
Comparable[] a = {2,1,7,1,6,3,18,21,23,12,190,156,156} ;
quickSort(a, 0, a.length -1);
for(int i = 0; i < a.length; i++){
System.out.println(a[i]);
}
}
private static void quickSort(Comparable[] a, int low, int high) {
if(high <= low) return;
int j = partition(a, low, high);
quickSort(a, low, j - 1);
quickSort(a, j + 1, high);
}
private static int partition(Comparable[] a, int low, int high) {
int i = low, j = high +1;
Comparable v = a[low];
while(true){
while(less(a[++ i], v))
if(i == high)
break;
while(less(v, a[--j]))
if(j == low)
break;
if(j <= i)
break;
exch(a, i, j);
}
exch(a, low, j);
return j;
}
private static void exch(Comparable[] a, int i, int j) {
Comparable t = null;
t = a[i];
a[i] = a[j];
a[j] = t;
}
public static boolean less(Comparable v, Comparable w){
return v.compareTo(w) < 0;
}
}