快速排序处理文件

昨晚看到的一家公司出的程序题:输入文件的内容格式为一行一条数据,每条数据有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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值