`
xiang37
  • 浏览: 429537 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

改进后的归并排序,对大文件归并排序

 
阅读更多

针对大文件,一次无法全部读入内存,可以采用将内容保存到文件的方式,进行归并;

可以改进之处,即分割文件,多线程,多机器处理;可以大大提高效率

 

package com.xiva.demo.sort;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.util.Arrays;
import java.util.LinkedList;

import org.apache.commons.io.IOUtils;

public class SortPractice<E extends Comparable<E>>
{
    
    private static int fileTempNum = 0;
    
    /**
     * 归并排序
     * @param array
     * @param low
     * @param high [参数说明]
     * 
     * @return void [返回类型说明]
     * @exception throws [违例类型] [违例说明]
     * @see [类、类#方法、类#成员]
     */
    @SuppressWarnings("unchecked")
    public void merge(E[] array, int low, int high)
    {
        int mid = (high + low) / 2;
        int s1 = low;
        int s2 = mid + 1;
        
        Object[] tempArr = new Object[high - low + 1];
        int tempIdx = 0;
        while (s1 <= mid && s2 <= high)
        {
            if (array[s1].compareTo(array[s2]) <= 0)
            {
                tempArr[tempIdx] = array[s1++];
                tempIdx++;
            }
            else
            {
                tempArr[tempIdx] = array[s2++];
                tempIdx++;
            }
        }
        
        if (s1 <= mid)
        {
            for (int i = s1; i <= mid; i++)
            {
                tempArr[tempIdx] = array[i];
                tempIdx++;
            }
        }
        
        if (s2 <= high)
        {
            for (int i = s2; i <= high; i++)
            {
                tempArr[tempIdx] = array[i];
                tempIdx++;
            }
        }
        
        for (int i = 0; i < tempArr.length; i++)
        {
            array[low + i] = (E)tempArr[i];
        }
    }
    
    public void mergeSort(E[] array, int low, int high)
    {
        
        if (low < high)
        {
            mergeSort(array, low, (high + low) / 2);
            mergeSort(array, (high + low) / 2 + 1, high);
            merge(array, low, high);
        }
    }
    
    public static void testmerge(int maxLineRead) throws IOException
    {
        
        File file = new File("E:\\data\\msisdn.txt");
        LinkedList<String> numList = new LinkedList<String>();
        BufferedReader bReader = new BufferedReader(new FileReader(file));
        
        LineNumberReader lineReader = new LineNumberReader(new FileReader(file));
        int tempFileNum = getLineNumber(lineReader, maxLineRead);
        
        File[] fileArray = new File[tempFileNum];
        
        for (int i = 0; i < tempFileNum; i++)
        {
            File tempFile = new File("E:\\data\\msisdnSort" + i + ".txt");
            fileArray[i] = tempFile;
            
            if (!tempFile.exists())
            {
                tempFile.createNewFile();
            }
        }
        
        String line = bReader.readLine();
        
        long startTime = System.currentTimeMillis();
        int lineIndex = 1;
        int fileIndex = 0;
        while (line != null)
        {
            String trimLine = line.trim();
            if (!trimLine.equals(""))
            {
                numList.add(trimLine);
            }
            line = bReader.readLine();
            lineIndex++;
            if (lineIndex > maxLineRead)
            {
                lineIndex = 1;
                FileOutputStream oStream = new FileOutputStream(
                        fileArray[fileIndex], true);
                outputResult2File(numList, oStream);
                fileIndex++;
                numList = new LinkedList<String>();
            }
        }
        
        if (numList.size() > 0)
        {
            FileOutputStream oStream = new FileOutputStream(
                    fileArray[fileIndex], true);
            outputResult2File(numList, oStream);
        }
        long endTime = System.currentTimeMillis();
        System.out.println("MergeSort Time:" + (endTime - startTime));
        mergeSortUseFile(fileArray);
        long outTime = System.currentTimeMillis();
        System.out.println("MergeFile Time:" + (outTime - endTime));
    }
    
    private static int getLineNumber(LineNumberReader lineReader,
            int maxLineRead) throws IOException
    {
        
        String line = lineReader.readLine();
        
        while (line != null)
        {
            line = lineReader.readLine();
        }
        
        int lineNum = lineReader.getLineNumber();
        int tempFileNum = lineNum / maxLineRead;
        
        if (lineNum % maxLineRead != 0)
        {
            tempFileNum = tempFileNum + 1;
        }
        return tempFileNum;
    }
    
    private static void outputResult2File(LinkedList<String> numList,
            FileOutputStream oStream) throws IOException
    {
        SortPractice<String> sort = new SortPractice<String>();
        
        int size = numList.size();
        String[] array = new String[size];
        
        for (int j = 0; j < size; j++)
        {
            array[j] = numList.removeFirst();
        }
        
        sort.mergeSort(array, 0, size - 1);
        
        for (int i = 0; i < array.length; i++)
        {
            IOUtils.write(array[i], oStream);
            IOUtils.write(System.getProperty("line.separator"), oStream);
        }
    }
    
    public static void mergeSortUseFile(File[] fileArray) throws IOException
    {
        
        int arrLen = fileArray.length;
        if (arrLen < 2)
        {
            return;
        }
        
        int tempFileNum = arrLen / 2;
        
        if (arrLen % 2 != 0)
        {
            tempFileNum = tempFileNum + 1;
        }
        
        File[] tempFileArray = new File[tempFileNum];
        
        for (int i = 0; i < tempFileNum; i++)
        {
            File tempFile = new File("E:\\data\\msisdnMerge" + fileTempNum + i + ".txt");
            tempFileArray[i] = tempFile;
            
            if (!tempFile.exists())
            {
                tempFile.createNewFile();
            }
        }
        
        fileTempNum = fileTempNum + tempFileNum;
        
        int fileIndex = 1;
        while (fileIndex < arrLen)
        {
            mergeFile(fileArray[fileIndex - 1],
                    fileArray[fileIndex],
                    tempFileArray[fileIndex / 2]);
            fileIndex = fileIndex + 2;
        }
        
        if(arrLen%2 != 0)
        {
            tempFileArray[tempFileNum - 1] = fileArray[arrLen - 1];
        }
        
        mergeSortUseFile(tempFileArray);
    }
    
    public static void mergeFile(File file1, File file2, File tempFile)
            throws IOException
    {
        BufferedReader file1Reader = new BufferedReader(new FileReader(file1));
        BufferedReader file2Reader = new BufferedReader(new FileReader(file2));
        FileOutputStream oStream = new FileOutputStream(tempFile, true);
        String obj1 = file1Reader.readLine();
        String obj2 = file2Reader.readLine();
        
        while (obj1 != null && obj2 != null)
        {
            if (obj1.compareTo(obj2) <= 0)
            {
                IOUtils.write(obj1, oStream);
                IOUtils.write(System.getProperty("line.separator"), oStream);
                obj1 = file1Reader.readLine();
            }
            else
            {
                IOUtils.write(obj2, oStream);
                IOUtils.write(System.getProperty("line.separator"), oStream);
                obj2 = file2Reader.readLine();
            }
        }
        
        if (obj1 != null)
        {
            while (obj1 != null)
            {
                IOUtils.write(obj1, oStream);
                IOUtils.write(System.getProperty("line.separator"), oStream);
                obj1 = file1Reader.readLine();
            }
        }
        
        if (obj2 != null)
        {
            while (obj2 != null)
            {
                IOUtils.write(obj2, oStream);
                IOUtils.write(System.getProperty("line.separator"), oStream);
                obj2 = file2Reader.readLine();
            }
        }
        
    }
    
    public static void testArraySort()
    {
        SortPractice<Integer> sort = new SortPractice<Integer>();
        
        Integer num01 = new Integer(12);
        Integer num02 = new Integer(13);
        Integer num03 = new Integer(44);
        Integer num04 = new Integer(3);
        Integer num05 = new Integer(13);
        Integer num06 = new Integer(5);
        Integer num07 = new Integer(7);
        
        Integer[] array = {num01, num02, num03, num04, num05, num06, num07,
                num04, num06, num01};
        
        sort.mergeSort(array, 0, array.length - 1);
        System.out.println(Arrays.toString(array));
        
    }
    
    public static void main(String[] args) throws IOException
    {
        testmerge(100000);
    }
    
}

 

分享到:
评论

相关推荐

    改进的归并排序算法

    在`improved_merge_sort.cpp`文件中,我们可以期待看到如何实现这两种改进的归并排序方法。代码可能包含了如何避免回写以及如何使用循环结构替代递归的具体实现细节。分析和理解这段代码可以帮助我们深入理解归并...

    MATLAB实现插入排序、二分归并排序、归并排序.rar

    不同之处在于,归并排序不使用二分查找,而是将数组分为两半,然后对每一半进行排序,再合并。归并排序在MATLAB中实现时,也需要递归地将数组划分为更小的部分,直到每个部分仅包含一个元素,然后逐步合并这些元素,...

    归并排序C语言实现

    7. **稳定性**:归并排序是稳定的排序算法,即相等的元素在排序后的相对位置不会改变。在合并过程中,如果遇到两个元素相等,我们会先将来自左边子数组的元素放入结果数组,确保了稳定性。 8. **优化技巧**: - ...

    归并排序 归并排序示例

    - **过程**:计算中间位置 `m`,递归地对左侧和右侧的子数组进行归并排序,然后调用 `guibing` 函数完成合并。 3. **主函数 `main`**: - 定义了一个包含乱序整数的数组 `ary`,调用 `merge_sort` 对数组进行排序...

    java实现归并排序

    Java 实现归并排序是一种常用的排序算法,通过分治策略将原始数组分成小组,然后对每个小组进行排序,最后将排序好的小组合并成一个有序数组。下面是 Java 实现归并排序的知识点总结: 基本思想 归并排序的基本...

    三路归并_C语言_三路归并排序_三路归并_

    三路归并排序的核心是将一个大数组分为三个较小的子数组,分别对这三个子数组进行排序,然后将排序后的子数组合并成一个有序的大数组。这种方法可以有效地处理具有大量重复元素的情况,因为它避免了在合并过程中不必...

    归并排序算法实现

    归并排序是一种经典的排序算法,采用分治法的思想,将待排序数组分为若干个子序列,这些子序列是已排序的,然后再按照一定的方式合并这些子序列得到最终排序后的数组。归并排序在实际应用中非常广泛,尤其在处理大...

    插入排序、选择排序、希尔排序、堆排序、冒泡、双向冒泡、快速排序、归并排序、递归的归并排序、基数排序

    9. 递归的归并排序:归并排序通常使用递归实现,通过递归调用自身对数组的前半部分和后半部分进行排序,然后用归并操作合并结果。这种递归方式使算法具有清晰的逻辑结构。 10. 基数排序:基数排序是一种非比较型...

    归并排序算法实现(排序算法系列1)

    在给定的压缩包文件中,"归并排序"可能是实现这个算法的源代码文件。通过查看和分析这段代码,我们可以更深入地理解归并排序的内部机制,学习如何在实际编程项目中应用这种排序算法。 总结来说,归并排序是一种分治...

    直接插入排序 冒泡排序 快速排序 直接选择排序 堆排序 二路归并排序 C#源代码

    6. **二路归并排序**:将数组分成两半,分别对左右两部分进行排序,然后合并两个已排序的部分。C#实现中,通常需要额外的空间来存储中间结果,所以是稳定的排序算法。二路归并排序的时间复杂度在所有情况下都保持在O...

    二路归并排序

    归并排序是一种基于比较的排序算法,它将待排序的记录分成两个或多个部分,然后对每个部分进行排序,最后将已排序的部分合并成一个有序的序列。 二路归并排序 二路归并排序是指将两个有序表归并成一个有序表的过程...

    C++实现希尔、快速、堆排序、归并排序算法

    4. 归并排序的合并过程中要注意避免不必要的元素复制,可以使用指针或迭代器来减少内存操作。 这些排序算法各有优缺点,适用场景也不同。希尔排序适合处理大规模且接近有序的数据;快速排序在大部分情况下性能优秀...

    归并排序Java_归并排序_

    归并排序的基本思想是将待排序的序列分成两个或更多的子序列,对每个子序列分别进行排序,然后将排序后的子序列合并成一个有序序列。这个过程会递归地应用于每个子序列,直到所有子序列只剩下一个元素或者为空。 在...

    归并排序,排序等算法,数据结构,快速排序,链表排序

    归并排序将大问题分解为小问题,然后逐步合并这些小问题的解以得到最终解决方案。它的主要步骤包括: 1. 分解:将待排序的序列分为两半。 2. 解决:对每一半递归地进行归并排序。 3. 合并:将两个已排序的子序列...

    归并排序插入排序C++代码

    1. **基本原理**:归并排序将待排序的序列分为两半,对每一半递归地进行归并排序,然后将两个已排序的半部分合并成一个完整的有序序列。这个过程就像合并两个已经排好序的书架上的书籍。 2. **分治策略**:归并排序...

    数据结构堆排序 快速排序 归并排序

    归并排序的特点是稳定性,即相等的元素在排序后相对位置不会改变。此外,由于涉及到额外的存储空间,归并排序在内存受限的情况下可能不如其他原地排序算法。 这三种排序算法在性能上各有特点。堆排序的时间复杂度为...

    快速排序、归并排序等排序算法比较

    快速排序、归并排序、基数排序等排序算法比较,比较时间性能,采用C++语言实现。。。

    排序-归并排序(Merge sort)

    归并排序(Merge Sort)是一种基于分治策略的高效排序算法,它的主要思想是将大问题分解成小问题,然后逐个解决小问题,最后再将解决好的小问题合并成解决大问题的答案。这种算法在计算机科学中有着广泛的应用,尤其...

    归并排序单步演示软件

    归并排序的基本思想是将大问题分解为小问题来解决,然后将小问题的解合并成大问题的解。具体步骤如下: 1. **分解**:将待排序的数组分为两个相等(或接近相等)的部分。 2. **排序**:对每个部分独立进行归并排序...

    冒泡排序,选择排序,插入排序,希尔排序,堆排序,归并排序,快速排序源码实现

    将待排序的序列分为两半,分别对这两半进行排序,然后将排序后的两个子序列合并成一个有序序列。源码实现中,需要递归地进行分治操作,以及一个合并函数来合并两个已排序的子序列。 7. **快速排序**:快速排序由C.A...

Global site tag (gtag.js) - Google Analytics