现在的位置: 首页 > 综合 > 正文

第三周作业 — 冒泡排序和归并排序

2018年05月14日 ⁄ 综合 ⁄ 共 3639字 ⁄ 字号 评论关闭

对于较少的数进行排序,冒泡和归并算法的优势区分并不明显,然而,这次对长度为1000000的数组进行排序。使用冒泡排序算法,简直无情,历时43分钟有余(2619秒)!而归并排序算法对其实现仅仅使用了264毫秒,你没看错!相差的除了数值还有一个数量级!由此可见,算法的优化对于机器处理来说,其重要性不言而喻。

冒泡排序参考资料:http://zh.wikipedia.org/wiki/%E5%86%92%E6%B3%A1%E6%8E%92%E5%BA%8F 

归并排序参考资料:http://zh.wikipedia.org/wiki/%E5%90%88%E4%BD%B5%E6%8E%92%E5%BA%8F

程序实现:

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.util.Scanner;

public class Txt2Sort {
	
	//返回冒泡排序所用时间
	public long bubbleSort(int[] dataArray){
		DateFormat dfDefault = DateFormat.getInstance();
		long startTime = System.currentTimeMillis();
		System.out.println("\n冒泡排序开始时间:"+dfDefault.format(startTime));
		
		//冒泡排序算法
		for(int i=1,lineCount=dataArray.length;i<lineCount;i++)
			for(int j=0;j<lineCount-i;j++){
				if(dataArray[j]>dataArray[j+1]){
					int t = dataArray[j];
					dataArray[j] = dataArray[j+1];
					dataArray[j+1] = t;
				}
			}
		long endTime = System.currentTimeMillis();
		System.out.println("冒泡排序结束时间:"+dfDefault.format(endTime));
		long useTimeSeconds = (long)((endTime - startTime)/1000); 
		return useTimeSeconds;
	}
	
	//写入文件使用时长
	public long writeToFile(int[] array,String fileName) throws FileNotFoundException{

		DateFormat dfDefault = DateFormat.getInstance();//获取时间,格式:3/27/14 10:50 PM
		PrintWriter pw = new PrintWriter(new File(fileName));
		
		long startTime = System.currentTimeMillis();
		System.out.println("\n写入文件开始时间:"+dfDefault.format(startTime));
		for(int i=0,lineCount=array.length;i<lineCount;i++){
			pw.println(array[i]);
		}
		pw.close();
		long endTime = System.currentTimeMillis();
		System.out.println("写入文件结束时间:"+dfDefault.format(endTime));
		long useTimeMills = (long)(endTime - startTime); //单位:毫秒
		return useTimeMills;
	}
	
	//返回归并排序使用的时间
	public long mergeSort(int[] needSortArray,int arrayLength,String fileName) throws FileNotFoundException{
		int[] medium = new int[arrayLength];
		
		DateFormat dfDefault = DateFormat.getInstance();
		long startTime = System.currentTimeMillis();
		System.out.println("归并排序开始时间:"+dfDefault.format(startTime));
		//排序
		MergeAll(needSortArray, medium, arrayLength);
		long endTime = System.currentTimeMillis();
		System.out.println("归并排序结束时间:"+dfDefault.format(endTime));
		
		this.writeToFile(needSortArray, fileName);
		long useTimeSeconds = (long)(endTime - startTime); 
		return useTimeSeconds;
	}
	
	//一次相邻数组排序
	public void MergeFirst(int[] r,int[] r1, int s,int m,int t){
		//相邻有序序列r[s]~r[m]和r[m+1]~r[t],合成有序序列r1[s]~r1[t]
		//i,j分别指向相邻有序序列的当前元素,k指向合成有序序列的当前元素
		int i=s,j=m,k=s;
		while(i<m && j<t){
			if(r[i]<=r[j])
				r1[k++] = r[i++];
			else
				r1[k++] = r[j++];
		}
		//处理未排序的序列,前半部分和后半部分
		if(i<m)
			while(i<m)
				r1[k++]=r[i++];
		else
			while(j<t)
				r1[k++]=r[j++];		
	}
	
	//一层相邻数组排序,从下标为0开始存放待排序列
	public void MergeSecond(int[] r,int[] r1,int n,int h){
		int i=0;
		while(i<=n-2*h){
			MergeFirst(r, r1, i,i+h,i+2*h);
			i+=2*h;
		}
		//最后一个序列长度小于h(子序列的数组长度)
		if(i<n-h)
			MergeFirst(r, r1, i,i+h,n);
		//排至剩下最后一个子序列
		else
			for(int k=i;k<n;k++)
				r1[k]=r[k];
	}
	
	//全体二路归并排序非递归实现
	public void MergeAll(int[] r,int[] r1,int n){
		int h=1;//h为初始子序列(h)长度	
		while(h<n){
			MergeSecond(r, r1, n, h);//待排序列r传至r1
			h=2*h;
			MergeSecond(r1, r, n, h);//待排序列r1传回r
			h=2*h;
		}
	}
	
	//全体二路归并排序递归实现
	
	public static void main(String[] args) throws FileNotFoundException{
		//从文件读取数据
		int[] readCount = new int[1000000];
		Scanner scan = new Scanner(new File(args[0]));//第一个个参数指定读取的文件名
		while(scan.hasNextInt()){
			for(int n=0,lineCount= readCount.length;n<lineCount;n++){
				readCount[n] = scan.nextInt();
			}
		}
		scan.close();
		
		//冒泡排序调用,返回排序时长
		Txt2Sort t = new Txt2Sort();
		long useSortTime = t.bubbleSort(readCount);
		System.out.println("\n冒泡排序法使用时长:"+useSortTime+" seconds");
		
		//写入文件调用,返回写入时长,第二个参数指定生成的文件名
		long useWriteTime = t.writeToFile(readCount,args[1]);
		System.out.println("写入文件使用时长:"+useWriteTime+" mills");
		long bubbleUseAllTime = useSortTime+useWriteTime;
		System.out.println("冒泡排序总共使用时长:"+bubbleUseAllTime+" seconds");
		
		//归并排序调用,返回排序时长
		long MegerUseAllTime = t.mergeSort(readCount, readCount.length,args[1]);
		System.out.println("归并排序使用时长:"+MegerUseAllTime+" mills");
	}
}

测试结果:

抱歉!评论已关闭.