一、快速排序和插入排序
首先考虑单独的快速排序和插入排序算法,这里利用算法导论第三版的伪码进行展示。
1、快速排序
代码实现:
public void quickSort(int[] arr, int left, int right) {
if (left> right) {
int mid = partition(arr, left, right);
quickAndInsertSort(arr, left, mid - 1);
quickAndInsertSort(arr, mid + 1, right);
}
}
public int partition(int[] arr, int left, int right) {
int mid=left+(right-left)/2;
getThreeMid(arr,left,mid,right);//对主元选取进行优化,此处选择第一个、中间、最后一个的中间值作为主元。
int base = arr[right];
int p = left - 1;
for (int i = left; i < right; i++) {
if (arr[i] <= base) {
p++;
exchange(arr,p,i);
}
}
p++;
exchange(arr,p,right);
return p;
}
public void getThreeMid(int[] arr,int left,int mid,int right){
if(arr[left]>arr[right])
exchange(arr,left,right);
if(arr[mid]<arr[right])
{
if(arr[mid]>arr[left])
exchange(arr,mid,right);
else
exchange(arr,left,right);
}
}
public void exchange(int[] arr,int q,int p){
int temp=arr[q];
arr[q]=arr[p];
arr[p]=temp;
}
2、插入排序
伪代码:
实现代码:
public void insertSort(int[] arr, int left, int right) {
for (int i = left; i <= right; i++) {
int temp=arr[i];
int j = i - 1;
for (; j >= left; j--) {
if (temp< arr[j]) {
arr[j+1]=arr[j];
} else
break;
}
arr[j+1]=temp;
}
}
二、快速排序优化
仅需要在递归求解时将规模小于k的子问题使用插入排序,此处的k为全局变量,可自行设置。
public void quickAndInsertSort(int[] arr, int left, int right) {
if (right - left + 1 > k) {
int mid = partition(arr, left, right);
quickAndInsertSort(arr, left, mid - 1);
quickAndInsertSort(arr, mid + 1, right);
}else
{
insertSort(arr, left, right);
}
}
三、完整源码
包括生成随机数写入文件,从文件中读取随机数、测试排序时间等。
package algorithm;
import org.junit.Test;
import java.io.*;
import java.util.Arrays;
import java.util.Random;
public class project1 {
private int k = 0;
@Test
public void project1Test() {
int len = 100000;
int[] arr = new int[100 * len];
int[] ks={0,1,2,3,4,5,6,7,8,9,10,50,100,200,500};
for(int i=0;i<ks.length;i++)
{
k=ks[i];
getData(arr, len);//从文件中读取数据
long nStartTime = System.nanoTime();
quickAndInsertSort(arr, 0, arr.length - 1);
long nEndTime = System.nanoTime();
System.out.println("k=" + k + "时算法执行时间" + (nEndTime-nStartTime)+"ns");
}
int[] arr1 = new int[100 * len];
getData(arr1, len);//从文件中读取数据
long nStartTime = System.nanoTime();
Arrays.sort(arr1);
long nEndTime = System.nanoTime();
System.out.println("系统排序算法执行时间" + (nEndTime-nStartTime)+"ns");
}
public void quickAndInsertSort(int[] arr, int left, int right) {
if (right - left + 1 > k) {
int mid = partition(arr, left, right);
quickAndInsertSort(arr, left, mid - 1);
quickAndInsertSort(arr, mid + 1, right);
}else{
insertSort(arr, left, right);
}
}
public void exchange(int[] arr,int q,int p){
int temp=arr[q];
arr[q]=arr[p];
arr[p]=temp;
}
public int partition(int[] arr, int left, int right) {
int mid=left+(right-left)/2;
getThreeMid(arr,left,mid,right);
int base = arr[right];
int p = left - 1;
for (int i = left; i < right; i++) {
if (arr[i] <= base) {
p++;
exchange(arr,p,i);
}
}
p++;
exchange(arr,p,right);
return p;
}
public void getThreeMid(int[] arr,int left,int mid,int right){
if(arr[left]>arr[right])
exchange(arr,left,right);
if(arr[mid]<arr[right])
{
if(arr[mid]>arr[left])
exchange(arr,mid,right);
else
exchange(arr,left,right);
}
}
public void insertSort(int[] arr, int left, int right) {
for (int i = left; i <= right; i++) {
int temp=arr[i];
int j = i - 1;
for (; j >= left; j--) {
if (temp< arr[j]) {
arr[j+1]=arr[j];
} else
break;
}
arr[j+1]=temp;
}
}
//从文件中读取随机数
public void getData(int[] arr, int l) {
//将稀疏矩阵从文件中读取出来
BufferedReader bufferedReader = null;
//为保存的数组分配空间
try {
InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream(new File("F:\java\leetcode\src\algorithm\data.dat")));
bufferedReader = new BufferedReader(inputStreamReader);
String line = null;
int i = 0;
//按行读取
while ((line = bufferedReader.readLine()) != null) {
if (i == l)
break;
if (null != line) {
//将按行读取的字符串按空格分割,得到一个string数组
String cut=" ";
String[] strings = line.split(cut);
//依次转换为int类型存入到分配好空间的数组中
for (int k = 0; k < strings.length; k++) {
arr[i * 100 + k] = Integer.valueOf(strings[k]);
}
//行数加1
i++;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
//生成随机数存放到文件中
@Test
public void saveData() {
File file = new File("F:\java\leetcode\src\algorithm\data.dat");
FileWriter out = null;
try {
out = new FileWriter(file);
for (int i = 0; i < 1000000; i++) {
for (int j = 0; j < 100; j++) {
int temp = new Random().nextInt();
String content = String.valueOf(temp);
out.write(content + "\t");
}
out.write("\r\n");
}
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}