实验要求
1、归并排序和快速排序效率比较
2、数据量:3个序列:随机序列,顺序序列,逆序序列
(每个序列的数据量均为10w)
实验分析(涉及的问题)
1、文件(.txt文件)中数据的读取和写入(数据以空格间隔,每行10个数据)
2、归并排序和快速排序的算法设计
3、排序所用时间的计算
实验环境
语言:java
环境:IDEA
实验代码
MergeSort.java
//归并排序,(含读取和写文件,计算执行时间)
public class MergeSort {
public int[] A;
public MergeSort(int[] array) {
this.A = array.clone();
}
public int[] SortResult()
{
sort(0, A.length - 1);
return A;
}
public void sort(int low, int high) {
if (low < high) {
int mid = (low + high) / 2;
//划分子序列
sort(low, mid);
sort(mid + 1, high);
//合并
merge(low, mid, high);
}
}
public void merge(int low, int mid, int high) {
// 声明新的数组,临时储存归并结果
int[] B = new int[high - low + 1];
int i = 0;
//左边序列和右边序列起始下标
int j = low;
int k = mid + 1;
//当有一个序列全部合并之后就结束
while (j <= mid && k <= high) {
if (A[j] <= A[k]) {
B[i] = A[j];
j++;
} else {
B[i] = A[k];
k++;
}
i++;
}
// 如果左边序列还有剩余就全部放进临时数组
while (j <= mid) {
B[i] = A[j];
i++;j++;
}
//如果有变序列还有剩余就全部放进临时数组
while (k <= high) {
B[i] = A[k];
i++;k++;
}
//将临时数组拷贝到原数组相应的位置
for (int t = 0; t < i; t++) {
A[low + t] = B[t];
}
}
}
QuickSort.java
//快速排序
public class QuickSort {
public int[] arr;
public QuickSort(int[] array) {
this.arr = array.clone();
}
public int[] SortResult() {
sort(arr, 0, arr.length - 1);
return arr;
}
public void sort(int[] arr, int left, int right) {
int tmp = arr[(left+right)/2], i = left, j = right;
while(i <= j) {
while(arr[j]>tmp) j--;
while(arr[i]<tmp) i++;
if(i<=j) {
int t = arr[i]; arr[i] = arr[j]; arr[j] = t;
i++;
j--;
}
}
if(i<right) sort(arr,i, right);
if(j>left) sort(arr,left, j);
}
}
TimeCounter.java
import java.io.*;
//归并排序和快速排序效率比较
public class TimeCounter {
static int size = 100001;//十万条数据
static int[] array = new int[size];
static int[] array_out=new int[size];
public static void main(String[] args) {
//时间变量(开始时间,结束时间)
long QuickStart,QuickEnd,MergeStart,MergeEnd;
/*******************************随机序列,读取一次***************************************/
readFile("Random_sequence.txt");
//快排,记录时间,并将排序结果写入txt
QuickStart = System.currentTimeMillis();
QuickSort quickSort1=new QuickSort(array);
array_out=quickSort1.SortResult();
QuickEnd = System.currentTimeMillis();
writeFile("Random_quick_out.txt");
//归排,记录时间,并将排序结果写入txt
MergeStart = System.currentTimeMillis();
MergeSort mergeSort1=new MergeSort(array);
array_out=mergeSort1.SortResult();
MergeEnd = System.currentTimeMillis();
writeFile("Random_merge_out.txt");
//进行时间的比较
System.out.println("随机序列排序所用时间:");
System.out.println("quick sort: " + (QuickEnd - QuickStart) + "毫秒");
System.out.println("merge sort: " + (MergeEnd - MergeStart) + "毫秒");
/*******************************顺序序列,读取一次***************************************/
readFile("Sequential_sequence.txt");
//快排,记录时间,并将排序结果写入txt
QuickStart = System.currentTimeMillis();
QuickSort quickSort2=new QuickSort(array);
array_out=quickSort2.SortResult();
QuickEnd = System.currentTimeMillis();
writeFile("Sequential_quick_out.txt");
//归排,记录时间,并将排序结果写入txt
MergeStart = System.currentTimeMillis();
MergeSort mergeSort2=new MergeSort(array);
array_out=mergeSort2.SortResult();
MergeEnd = System.currentTimeMillis();
writeFile("Sequential_merge_out.txt");
//进行时间的比较
System.out.println("顺序序列排序所用时间:");
System.out.println("quick sort: " + (QuickEnd - QuickStart) + "毫秒");
System.out.println("merge sort: " + (MergeEnd - MergeStart) + "毫秒");
/*******************************逆序序列,读取一次***************************************/
readFile("Reverse_sequence.txt");
//快排,记录时间,并将排序结果写入txt
QuickStart = System.currentTimeMillis();
QuickSort quickSort3=new QuickSort(array);
array_out=quickSort3.SortResult();
QuickEnd = System.currentTimeMillis();
writeFile("Reverse_quick_out.txt");
//归排,记录时间,并将排序结果写入txt
MergeStart = System.currentTimeMillis();
MergeSort mergeSort3=new MergeSort(array);
array_out=mergeSort3.SortResult();
MergeEnd = System.currentTimeMillis();
writeFile("Reverse_merge_out.txt");
//进行时间的比较
System.out.println("逆序序列排序所用时间:");
System.out.println("quick sort: " + (QuickEnd - QuickStart) + "毫秒");
System.out.println("merge sort: " + (MergeEnd - MergeStart) + "毫秒");
}
//读取txt文件,存储到数组中
public static void readFile(String input_pathname) {
// 绝对路径或相对路径都可以
// String pathname = "D:\\data\\Sequential_sequence.txt";
// String pathname = "Sequential_sequence.txt";
String pathname = input_pathname;
try (FileReader reader = new FileReader(pathname);
BufferedReader br = new BufferedReader(reader)) {
int j = 0;
String line;
// 一次读入一行数据
while ((line = br.readLine()) != null) {
String[] s = line.split(" ");
for (int i = 0; i < 10; i++) {
array[j] = Integer.parseInt(s[i]);
j++;
}
}
reader.close();
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//将排序好的序列写入文件
public static void writeFile(String output_pathname) {
File writeName = new File(output_pathname);
try (FileWriter writer = new FileWriter(writeName);
BufferedWriter out = new BufferedWriter(writer))
{
// 创建新文件,有同名的文件的话直接覆盖
writeName.createNewFile();
//将数组中的数据写入到文件中。每行各数据之间空格间隔,每行10个数
for (int i = 0; i < array_out.length - 1; i++) {
out.write(array_out[i] + " ");
if ((i + 1) % 10 == 0) { //一行够10个数就换行
out.write("\n");
}
}
out.flush();// 把缓存区内容压入文件
} catch (IOException e) {
e.printStackTrace();
}
}
}
实验结果
难点
快速排序按照网上的写法,可能会遇到栈溢出的情况,解决办法:换代码