外部插入在二进制文件上排序

时间:2014-12-11 19:30:24

标签: java insertion-sort external-sorting

我正在尝试在一个二进制文件上执行外部插入排序,该二进制文件充满0到1之间的随机双精度。我在“value”和“temp”分配之后添加了一堆println语句,看起来他们正在获取每次迭代都是相同的值。我认为我没有正确遍历文件。

public class ExternalFileSort 
{

    public static void sort(String filename, int length) throws IOException
    {
        int i, j;
        double value, temp;


        RandomAccessFile file = new RandomAccessFile(filename, "rw");

        for (i = 1; i < length; i++)
        {
            file.seek(i);
            temp = file.readDouble();

            j = i-1;
            file.seek(j);
            value = file.readDouble();


            while (j >= 0 && value > temp)
            {
                file.seek(j+1);
                file.writeDouble(value);
                j--;
            }

            file.seek(j+1);
            file.writeDouble(temp);

        }


        file.close();
    }
}

2 个答案:

答案 0 :(得分:0)

假设您根据该定义在文件中写入了双打(这是强制性先决条件)https://docs.oracle.com/javase/7/docs/api/java/io/DataOutput.html#writeDouble%28double%29

RandomAccessFile file = new RandomAccessFile(filename, "rw");
long currentPosition = 0L;
while (currentPosition < file.length()) {
    double current = file.readDouble();
    double min = current;
    long minPosition = currentPosition;
    // Find the smallest value in the rest of the file
    while (currentPosition < file.length()) {
        double candidate = file.readDouble();
        if (candidate < min) {
            min = candidate;
            minPosition = file.getFilePointer() - 8;
        }
    }
    // Swap
    file.seek(minPosition);
    file.writeDouble(current);
    file.seek(currentPosition);
    file.writeDouble(min);
    currentPosition = file.getFilePointer();
}

未经测试,但您明白了。

答案 1 :(得分:0)

您应该知道的第一件事是double类型使用8个字节。如果您的文件是双精度二进制数组,则前8个字节将对应于第一个双精度数,后8个字节将对应于第二个双精度数,依此类推。例如,如果在执行file.seek(1)后尝试读取双精度数,则会读取一个混乱的值,因为它将由第一个双精度的7个字节和第二个的第一个字节组成。
首先将整个文件读入双精度数组,在数组中执行排序算法,然后将生成的数组写回磁盘,会更容易,更有效。对于第一部分,您将使用int size = file.length() / 8;计算双打数。然后,您将创建一个具有此大小的双精度数组,并使用相应数量的file.readDouble()调用读取它们 如果您必须直接在二进制文件上执行整个操作,请不要忘记在搜索操作中文件内部的双精度实际位置应乘以8,以便将它们转换为字节位置。例如:第一个双头位于0位置,第二个位于8位,第三个位于16位,依此类推。