2014-09-14 4 views
0

Я пытался оптимизировать эту версию mergesort, но занимает слишком много времени, чтобы отсортировать около 3 миллионов регистров. Где я делаю это неправильно? Я был бы признателен за помощь, спасибо.Почему сортировка слияния занимает слишком много времени?

Persona - это класс, который имеет строку и целое число, на всякий случай, что вы, ребята, хотите знать, чтобы помочь мне.

public class Mergesort { 
    private ArrayList<Persona> numbers = new ArrayList(); 
    private ArrayList<Persona> helper; 
    private int number; 
    private boolean ascending; 


    public void sort(ArrayList<Persona> values, boolean ascending) { 
    this.numbers = values; 
    this.ascending = ascending; 
    number = values.size(); 
    helper = new ArrayList(); 
    mergesort(0, number - 1); 
    } 

    /** 
    * Determines the middle of the array to sort the left side and the right side 
    * Then it merges both arrays. 
    * @param low 
    * @param high 
    */ 
    private void mergesort(int low, int high) { 
    // check if low is smaller then high, if not then the array is sorted 
    if (low < high) { 
     // Get the index of the element which is in the middle 
     int middle = low + (high - low)/2; 
     // Sort the left side of the array 
     mergesort(low, middle); 
     // Sort the right side of the array 
     mergesort(middle + 1, high); 
     // Combine them both 
     merge(low, middle, high); 
    } 
    } 

    /** 
    * Merges the arrays. 
    * @param low 
    * @param middle 
    * @param high 
    */ 
    private void merge(int low, int middle, int high) { 

    // Copy both parts into the helper array 
    for (int i = low; i <= high; i++) { 
      helper.add(i, numbers.get(i)); 
    } 

    int i = low; 
    int j = middle + 1; 
    int k = low; 
    // Copy the smallest values from either the left or the right side back 
    // to the original array 
    while (i <= middle && j <= high) { 
     if (helper.get(i).id <= helper.get(j).id) { 
     numbers.set(k, helper.get(i)); 
     i++; 
     } else { 
     numbers.set(k,helper.get(j)); 
     j++; 
     } 
     k++; 
    } 
    // Copy the rest of the left side of the array into the target array 
    while (i <= middle) { 
     numbers.set(k,helper.get(i)); 
     k++; 
     i++; 
    } 
    }} 
+0

Определить длиной. С чем вы сравниваете? – reto

+0

Более 4 минут. – Ranguro

+0

Я еще не видел отсортированный массив. – Ranguro

ответ

4

Вы никогда не ясно из содержания helper (которая не должна быть глобальной anyawy), что означает каждый раз, когда вы объединяете все больше и больше данных. Я действительно удивлен, что ты не ушел из памяти.

+0

Где я должен очищать помощника? – Ranguro

+1

'helper' должен быть локальной переменной в' merge() ', воссозданной при каждом вызове. Однако я еще не полностью отладил ваш код для других ошибок. Использование «помощника» кажется подозрительным. –

+0

Если я это сделаю, я получаю исключение java.lang.IndexOutOfBoundsException. – Ranguro

0

Ваш код работает и o/p является alryt? В функции слияния должен быть еще один цикл после первого цикла while. Первый цикл while завершен, потому что либо j> высокий, либо i> средний. Вы только что написали J> высокого состояния, дер нет я> средний condtn.After этого цикла Автошоу должен быть чем-то вроде Дис

if(j>high) 
{ 
while (i <= middle) { 
     numbers.set(k,helper.get(i)); 
     k++; 
     i++; 
    } 
} 
else 
{ 
while (j <= high) { 
     numbers.set(k,helper.get(j)); 
     k++; 
     j++; 
    } 
} 

N очистить хелперный