2013-05-04 14 views
5

Dodałem ten algorytm rekursywny BubbleSort do mojej gry, która działa na lwjgl. Próbuję posortować ArrayList obiektów "Cloud" przez float, który jest prędkością tej chmury.BubbleSort StackOverflowError

Z jakiegoś powodu czasami otrzymuję "java.lang.StackOverflowError" w wierszu, w którym sam wywołuję metodę.

Oto kod:

public void sort() { 
    for (int i = 0; i < clouds.size() - 1; i++) { 
     Cloud cl1 = clouds.get(i); 
     Cloud cl2 = clouds.get(i + 1); 
     if (cl1.getSpeed() < cl2.getSpeed()) { 
      continue; 
     } 
     clouds.set(i, cl2); 
     clouds.set(i+1, cl1); 
     this.sort(); 
    } 
} 

I tu są błędy Dostaję:

Sat May 04 20:28:45 CEST 2013 ERROR:null 
java.lang.StackOverflowError 
     at backgrounds.Clouds.sort(Clouds.java:224) 
[...] // The line above is repeated for some hundred times. 
+0

Polecam implementację porównywalną w klasie Cloud, korzystasz z kolekcji do przechowywania chmur, które wydaje (.size), więc Collectionssort() zajmie się tym za ciebie. Wymyślanie własnych metod jest jednak zabawne;) – arynaq

Odpowiedz

9

, co dzieje się, gdy dwa kolejne chmury mają taką samą prędkość.

cl1.getSpeed() < cl2.getSpeed() 

jest fałszywa, więc zamieniłem się chmury i sort nazywa się ponownie. W tej rozmowy

cl1.getSpeed() < cl2.getSpeed() 

nadal jest fałszywy, więc znowu zamienić i nazywają sort. To trwa wiecznie (lub lepiej: dopóki stos jest pełny).

Zmień < na <= i wszystko powinno działać poprawnie.

+0

Dzięki to działa! – Deconimus

4

To może być lepiej użyć wbudowanej metody sortowania dla tablic w Javie Arrays.sort() używać to wszystko, co musisz zrobić, to zastąpić metodę porównywania z metodą. Oto jak to wygląda.

@Override 
public int compareTo(Book other) { 
//compare logic here 
} 

Należy także wdrożyć Porównywalne to zrobić

6

możliwość porównania logika powinna przejść dwa chmurze obiektów, jeżeli są one same też -

zmienić, jeśli do -

if (cl1.getSpeed() <= cl2.getSpeed()) { 
    continue; 
} 
+0

Obie pozostałe odpowiedzi są poprawne, jednak jeśli używasz wbudowanej metody sortowania, lepiej jest unikać błędów, a użyty algorytm to prawdopodobnie quicksort lub mergesort, który jest szybszy niż sortowanie bąbelkowe. – aaronman

0

To może być dalej zoptymalizowany jako

public void sort() { 
    boolean swaps = false; 
    for (int i = 0; i < clouds.size() - 1; i++) { 
     Cloud cl1 = clouds.get(i); 
     Cloud cl2 = clouds.get(i + 1); 
     if (cl1.getSpeed() <= cl2.getSpeed()) { 
      continue; 
     } 
     swaps = true; 
     clouds.set(i, cl2); 
     clouds.set(i+1, cl1); 
    } 

    //Re-Iterate all the elements only if a swap is found 
    if(swaps) 
     this.sort(); 
} 
+0

Myślę, że tak się dzieje. Ale dzięki za odpowiedź. – Deconimus

+0

robienie tego byłoby szybsze, także naprawdę nie sądzę, że musisz wykonać rekurencyjne wywołanie tego! W każdym razie miło wiedzieć, że twój problem został rozwiązany – Akash

0

częstą przyczyną dotyczący przepełnienie stosu jest złym rekursywnym wywołaniem, które powstaje, gdy funkcje rekursywne nie mają poprawnego warunku zakończenia, więc kończy się ono wywoływaniem na zawsze. W twoim przypadku warunek zakończenia nie jest spełniony ze względu na znak "<", więc musisz zmienić to na "< =" to wszystko.

Powiązane problemy