您的位置:首页 > 编程语言 > Java开发

第三周作业-文件中百万的数据进行排序后再写入文件。(冒泡和归并分别实现)

2014-03-28 23:55 681 查看
程序源代码如下:

package 算法第三周;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;

public class Sort {
private static String filePath;//储存需要读取文件的路径
private static String line = "";//存储读取的一行字符
private static int tempInt;//存储读取的字符转换成数字后,然后再存储到ArrayList数组中。
//因为不涉及在数组中插入,删除数据,所以采用arraylist来遍历。
private static ArrayList<Integer> al = new ArrayList<Integer>();

public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("请输入读取的记事本文件的路径");
filePath = scan.next();
BufferedReader bf;
try {
bf = new BufferedReader(new FileReader(filePath));
//读取文件,将数据存储懂啊arraylist中。
while((line = bf.readLine()) != null) {
line = line.trim();
tempInt = Integer.parseInt(line);
al.add(tempInt);
}

//冒泡排序法。
/*for(int i=0; i<al.size()-1; i++){   //第一层循环是因为每次只能提取出一个最值到比较的终点
for(int j=0; j<al.size()-1-i; j++ ) {//第二层循环式每趟的比较次数。
if (al.get(j) > al.get(j+1)) {
tempInt = al.get(j);
al.set(j, al.get(j+1));
al.set(j+1, tempInt);
}
}
}
System.out.print("冒泡排序需要的时间是");*/
//归并排序
int[] arr = new int[al.size()];
for(int i=0;i<al.size();i++) { //arraylist数组内容复制到int数组中
arr[i] = al.get(i);
}
long time1 = System.currentTimeMillis();//获取系统时间
arr = mergeSort(arr);
System.out.print("归并排序所需要的时间是:");
System.out.print((System.currentTimeMillis() - time1)/60000.0 + "分钟");//重新获取系统时间,差值就是排序时间。
al.clear(); //对arraylist数组清空,便于下面的
for(int i=0;i<arr.length;i++) {
al.add(arr[i]);
}

//将排好序的数组中的文字写入到文件中。
System.out.println("\n请输入写入记事本文件的完整路径(包括文件名)");
filePath = scan.next();
scan.close();
BufferedWriter bw = new BufferedWriter(new FileWriter(filePath));
{
for(int i=0;i<al.size();i++) {
bw.write((String.valueOf(al.get(i))));
bw.newLine();//在文件中另起一行。
}
}
bw.flush();
bw.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

private static int[] mergeSort(int arr[]) {
//i和j分别是两个待归并序列的下标;
//t和m分别是两个待归并序列 的下标上限;
//h是待归并序列的元素个数;
//k是新数组的 下标。
int i = 0, h = 1, j = i + h, k = 0, n = arr.length,arr1[], t, m;
while(h < n) {//当归并序列的元素个数少于这个排序序列的元素的个数时,就继续排
i = 0;
j = i + h;
k = 0;
arr1 = new int
;
while(i <= n-2*h) {//归并后若后面还存在两个或以上的待归并序列时
t = j;m = j + h;
while(i<t && j<m) {//待归并序列下标小于上限时
if(arr[i] <= arr[j]) {
arr1[k++] = arr[i++];
} else {
arr1[k++] = arr[j++];
}
}
//比较完之后,当只剩下一个待归并序列时,会执行下面的其中一个while
while(i<t) {//左边待归并序列小于上限
arr1[k++] = arr[i++];
}
while(j<m) {//右边待归并序列小于上限
arr1[k++] = arr[j++];
}
i += h;//准备转下次归并
j += h;
}
//一下就是归并的收尾工作。
if(i < n-h) {//待归并序列多于一个,而不够两个时
t = j;
while(j<n && i<t) {
if(arr[j] <= arr[i]) {
arr1[k++] = arr[j++];
} else {
arr1[k++] = arr[i++];
}
}
while(i<t) {
arr1[k++] = arr[i++];
}
while(j<n) {
arr1[k++] = arr[j++];
}
} else {
while(i<n) {//只剩一个或不够一个待归并序列时
arr1[k++] = arr[i++];
}
}
h = 2*h;//准备下一趟归并
arr = arr1;//引用指向传给原来的数组,对下次归并所需要的新数组重新new,;显示出垃圾回收机制的好处。
}
return arr;
}
}
其中,冒泡排序时间及运行截图:



归并排序的运行时间及其截图:



其中冒泡排序的下载链接和归并排序后写入的文件(下载链接)和源文件的下载链接

小小体会:

其中冒泡排序用了两小时多,而归并仅是用了0.18秒。这就是算法效率的差距,这也体现了一个好的算法的重要性。并且其中还体现了java的垃圾回收机制。

归并排序算法是思想是树上的,内容是绝对原创的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐