Este es exactamente el origen QuickSort en aquel entonces no había suficiente memoria RAM para ordenar en la memoria por lo que el procedimiento es almacenar resultados parciales en el disco.
Entonces, ¿qué se puede hacer es:
- Elige un pivote.
- Leer secuencialmente los datos del archivo y almacenar más baja que pivote en temp_file_1 y datos más grandes o iguales al pivote en temp_file_2
- Repetir el procedimiento en temp_file_1 y añadir el resultado a result_file
- Repetir el procedimiento para temp_file_2 y anexar la resultado de result_file
Cuando las piezas son lo suficientemente pequeños (como
2 acaba de intercambio directo de ellos
Lo suficiente como para ser clasificado en la memoria)
de esta manera podrás ordenar en trocea y almacena los resultados parciales en archivos temporales y tendrás un archivo final con el resultado ordenado.
EDIT Te dije que una clasificación rápida era posible.
Parece que necesitarías más espacio para los archivos temporales, después de todo.
Esto es lo que hice.
Creo un archivo de 40 mb con números separados por comas.
lo nombro input
:
input http://img200.imageshack.us/img200/5129/capturadepantalla201003t.png
de entrada es de 40 MB
Durante la clase, los archivos temporales con los cubos de "mayor que", "menor que" los valores se crean y cuando el tipo está terminado, los valores se envían a un archivo llamado (adivinen qué) output
processing http://img200.imageshack.us/img200/1672/capturadepantalla201003y.png
archivos temporales se crean con los resultados parciales
Por último, se suprimen todos los archivos temporales y el resultado se guarda en el archivo "salida" con la secuencia correcta ordenados de números:
output http://img203.imageshack.us/img203/5950/capturadepantalla201003w.png
Finalmente se crea el archivo "de salida", observe que es de 40 MB también
Aquí está el progr completa a.m.
import java.io.*;
import java.util.*;
public class FileQuickSort {
static final int MAX_SIZE = 1024*1024*16; // 16 megabytes in this sample, the more memory your program has, less disk writing will be used.
public static void main(String [] args) throws IOException {
fileQuickSort(new File("input"), new File("output"));
System.out.println();
}
//
static void fileQuickSort(File inputFile, File outputFile) throws IOException {
Scanner scanner = new Scanner(new BufferedInputStream(new FileInputStream(inputFile), MAX_SIZE));
scanner.useDelimiter(",");
if(inputFile.length() > MAX_SIZE && scanner.hasNextInt()) {
System.out.print("-");
// put them in two buckets...
File lowerFile = File.createTempFile("quicksort-","-lower.tmp",new File("."));
File greaterFile = File.createTempFile("quicksort-","-greater.tmp", new File("."));
PrintStream lower = createPrintStream(lowerFile);
PrintStream greater = createPrintStream(greaterFile);
PrintStream target = null;
int pivot = scanner.nextInt();
// Read the file and put the values greater than in a file
// and the values lower than in other
while(scanner.hasNextInt()){
int current = scanner.nextInt();
if(current < pivot){
target = lower;
} else {
target = greater;
}
target.printf("%d,",current);
}
// avoid dropping the pivot
greater.printf("%d,",pivot);
// close the stream before reading them again
scanner.close();
lower.close();
greater.close();
// sort each part
fileQuickSort(lowerFile , outputFile);
lowerFile.delete();
fileQuickSort(greaterFile , outputFile);
greaterFile.delete();
// And you're done.
} else {
// Else , if you have enough RAM to process it
//
System.out.print(".");
List<Integer> smallFileIntegers = new ArrayList<Integer>();
// Read it
while(scanner.hasNextInt()){
smallFileIntegers.add(scanner.nextInt());
}
scanner.close();
// Sort them in memory
Collections.sort(smallFileIntegers);
PrintStream out = createPrintStream(outputFile);
for(int i : smallFileIntegers) {
out.printf("%d,",i);
}
out.close();
// And your're done
}
}
private static PrintStream createPrintStream(File file) throws IOException {
boolean append = true;
return new PrintStream( new BufferedOutputStream(new FileOutputStream(file, append)));
}
}
El formato de los archivos es number,number,number,number
su formato actual es: n u m b e r , n u m b , b e r
Para corregir esto sólo hay que leer todo y saltar los espacios en blanco.
Agregue otra pregunta para eso.
¿Dónde está el problema con su código? ¿Qué enfoques has probado? –
sí, para escribir estos enteros en un archivo utilicé RandomAccessFile.writeChars(). Traté de usar writeInt() pero enteros unidos ... Así que writeChars() escribió enteros de esa manera, solo agregué una coma ... – Dmitry
@Dmitry: ¿qué hay de malo en tener el número '136' juntos, por qué? lo necesito como '1 3 6'? – OscarRyz