快速排序处理文件

来源:互联网 发布:如何运用办公软件 编辑:程序博客网 时间:2024/06/05 15:11

昨晚看到的一家公司出的程序题:输入文件的内容格式为一行一条数据,每条数据有2个字段用逗号分隔,第1个字段为排序用的Key,第二个字段为value。换行符为’\n’。

数据内容举例如下:

abe,xmflsflmfmlsmfs

abc,xmlmxlkmffhf

8fj3l,xxjfluu313ooo11

注意点:

  1. 本次的测试数据内容都是ASCII字符,无中文汉字。所以不必考虑字符集。

  2. 本次的测试数据中key的最大长度8,value的最大长度32。

  3. 请勿使用诸如java.util.Collections.sort(), java.util.Arrays.sort()这样的JDK提供的排序函数。

  4. 请勿使用多线程。

排序以key的升序,key的比较大小以String.compareTo()为准。最后排序完成的数据写入指定的输出文件。另外还提供一个指定的临时文件,在处理大量数据的时候会用到。
以下是我的代码:
主函数:
public static void main(String[] args) throws Exception {
long start = System.currentTimeMillis();
//方法体

    File inputFile = new File("data/input.data");    File outputFile = new File("data/output.data");    File tempFile = new File("data/temp.data");    if(!inputFile.exists()){        System.out.println("数据文件夹不存在!");    }    if(!outputFile.exists()){            outputFile.createNewFile();    }    if(!tempFile.exists()){        tempFile.createNewFile();    }    //调用test方法,主要是对文件的一些读写操作    test(inputFile, outputFile, tempFile);    long end = System.currentTimeMillis();    //输出程序运行时间    System.out.println("main:"+(end-start));}

test方法:
public static void test(File inputFile, File outputFile, File tempFile) throws Exception {
//用BufferedReader来对文件进行读取,整行读取觉得速度比较快
FileReader fReader = new FileReader(inputFile);
BufferedReader bufReader = new BufferedReader(fReader);
String read;
ArrayList list = new ArrayList();//保存读取的文件
while((read=bufReader.readLine())!=null){
list.add(read);
}
list.trimToSize();//除去ArrayList中预留元素的位置,节约内存
bufReader.close();
fReader.close();
quicksort(list, 0, list.size()-1);//调用快速排序的方法
//用FileOutputStream 进行写文件到outputFile
FileOutputStream out=new FileOutputStream(outputFile);
//逐行写文件
for (int i=0;i<=list.size()-1;i++) {
StringBuffer sb = new StringBuffer();
// System.out.println(list.get(i)+”\r\n”);
sb.append(list.get(i)+”\r\n”);
out.write(sb.toString().getBytes(“utf-8”));
}
out.close();
}
快速排序方法:
//主要用的是递归法来进行排序,当list的起始位置low和结束位置high相等时,递归结束
public static void quicksort(ArrayList list, int low, int high){
if(low < high){
int middle = getMiddle(list, low, high);//调用getMiddle方法,得到中轴位置
quicksort(list, low, middle-1);
quicksort(list, middle+1, high);
}
}
getMiddle方法:
/**
*
* @param list
* @param low list初始位置
* @param high list末尾位置
* @return 返回最终的low值,即中轴所在位置
*/
public static int getMiddle(ArrayList list, int low, int high){
String tempKey = list.get(low).toString();//将list起始位的数据作为轴
while(low < high){
//从后往前比较,如果list.get(high).toString()比tempKey 值大,位置不变,就比较下一位置的值
while(low < high && swap(list.get(high).toString(), tempKey)){
high –;
}
//如果list.get(high).toString()比tempKey 值小,把list.get(high).toString()的值赋值给list.get(low),然后从前往后比较值
list.set(low, list.get(high));
while(low < high && !swap(list.get(low).toString(), tempKey)){
low ++;
}
list.set(high, list.get(low));
}
//当所有值都比较完之后,把tempkey的值赋值给list.get(low),此时low的位置即为中轴的位置
list.set(low, tempKey);
return low;
}
swap方法:
/**
*
* @param str1
* @param str2
* @return 如果 str1的key值小于str2的key值,返回true,否则返回false
*/
public static boolean swap(String str1,String str2){

    String Key1,Key2;    Key1 = str1.split(",")[0];//将str1第一个逗号前的字符串赋值给key1    Key2 = str2.split(",")[0];//将str2第一个逗号前的字符串赋值给key2    if(Key2.compareTo(Key1)<0){        return true;    }    else{        return false;    }   }快速排序思想:假设将5 7 6 3 1 9  2 8进行升序排序,首先选一个中轴(一般选开头数值)来和其他数进行比较,把比中轴小的值放在它左边,比它大的放右边,第一次排序:**2 1 3** 5 **6 9 7 8**  //5前面都比5小,5后面都比5大第二次排序:(**1** 2 **3**) 5( 6 **9 7 8**)//2和6为轴第三次排序:1 2 3 5 6( **8 7** 9 )//9为轴第四次排序:1 2 3 5 6 (**7** 8 )9 //7为轴
0 0
原创粉丝点击