Array-List Bubble-Sort

javanoob2

Mitglied
Hallo Spezialisten, hallo Freaks,

ich grübel seit Stunden an folgendem Sachverhalt:
Array-List nach Bubble-Sort neu sortieren (eigenständige Sortierung programmieren).

Dazu habe ich mir folgende Idee gemacht:
Ich arbeite mit einer for-Schleife und darin mit einer if-Abfrage, die mittels
limV.get(x) > limV.get(x+1) vergleicht, ob die 1. Zahl in der ArrayList größer
ist, als die 2. Zahl. Falls ja, dann werden die beiden Zahlen getauscht.
Am Ende, so die Idee, sollten dann die Inhalte der ArrayList sortiert sein
(x = ist kleiner als x+1, x+1 ist kleiner als x+2, ...) Leider ist das Ergebnis nicht
richtig, und auch ein Error wird mir angezeigt.

Code:
java.lang.IndexOutOfBoundsException: Index: 5, Size: 5
    at java.util.ArrayList.rangeCheck(ArrayList.java:653)
    at java.util.ArrayList.get(ArrayList.java:429)
    at Beleg_SS_2016.BaustelleEinrichten.sortieren(BaustelleEinrichten.java:62)
    at Beleg_SS_2016.__SHELL3.run(__SHELL3.java:8)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at bluej.runtime.ExecServer$3.run(ExecServer.java:730)

So ist meine Programmier-Idee. Freue mich über Hinweise, damit ich das Problem meistern kann. Vielen Dank!

Java:
public class BaustelleEinrichten
{
    private static ArrayList<Baucontainer> bcListe = new ArrayList<Baucontainer>();
    private static ArrayList<Double> limV = new ArrayList<>();
    private static Kran kran;
    private static double limX;
   


  
    public static void einrichten(int n){
       
        Beleg2 id2 = new Beleg2();
        id2.createUUID();
      
 
        System.out.println("==================");
        for (int i = 0; i < n; i++){
            Random zufall = new Random();
            double breite   = zufall.nextDouble()*16+5;
            double laenge   = zufall.nextDouble()*21+20;
            double hoehe    = zufall.nextDouble()*5+1;
            Baucontainer bc = new Baucontainer(100+i*50, 200, laenge, breite);
            bc.setHoehe(hoehe);
            bc.setVisible(true);
            bcListe.add(bc);
            double volumen  = breite*hoehe*laenge;

           
            limV.add(volumen);
           
            limX = 150+i*50; // für eine neue Sortierung nach dem letzten Container
            System.out.println("Container-Nr.: " + i + " | Volumen: " + volumen + " cm³" + limV.get(i) + " ");
           
        }
        Baustrasse bs = new Baustrasse(0,50,1000,50,40);
        bs.setVisible(true);
        kran = new Kran(400, 300, 50, 350);
        kran.setVisible(true);   
       
    }
   
   
    public static void sortieren(){
       
        double limV2;
        double limV3;
       
     
      
        for (int x = 0;x<=bcListe.size()-1;x++){
       
            if (limV.get(x) > limV.get(x+1) ){
               
                System.out.println(x + ". Stelle " + limV.get(x));
                System.out.println(x + ". Stelle " + limV.get(x+1));
               
                limV2=limV.get(x);
                limV3=limV.get(x+1);
                limV.remove(x);
                limV.remove(x+1);
                limV.add(x,limV3);
                limV.add(x+1,limV2);
               
                for (int z = 0;z<=bcListe.size()-1;z++){
           
          
                 System.out.println(limV.get(z));
           
        }
              
             
               
           
               
            }
           
           
        
   
  
        }
       
        kran.ladeBaucontainerAuf(bcListe.get(0));
        kran.ladeBaucontainerAb(bcListe.get(0), 100, 150);
       
    }

  
   
  
}
 
) Leider ist das Ergebnis nicht
richtig
Bedeutet?

auch ein Error wird mir angezeigt.
Die Exception bekommst du, da du auf ein Element zugreifen willst welches es nicht gibt. Wenn du x und x+1 vergleichst dann reicht es wenn du bis zum vorletzten Element der Liste gehst. x ist dann das vorletzte und x+1 das letzte Element. Momentan gehst du aber mit x <= bclist.size()-1 bis zum letzten Element - somit ist x+1 nicht mehr in deiner Liste definiert 🙂

Gruß Robert
 
Hallo Robert,

habe ich denn mit
Java:
x <= bclist.size()-1
nicht genau das bezweckt, dass er eben nur bis zum vorletzten X geht? Bsp: bclist hat 5 Elemente, dann geht diese for-Schleife nur bis 5-1 also bis 4. Oder ist das ein Denkfehler?

Ich habe gerade nämlich die -1 rausgelöscht, durch -2 ersetzt, bzw auch probiert, einfach bclist.size() zu notieren, aber es kommt immer noch dieser Exception Fehler (die If-Zeile wird mir in BlueJ gelb markiert).

VG
 
Ich glaube du hast einen wesentlichen Denkfehler.
Indizes fangen bei 0 an.
Wenn du schreibst x <= bclist.size()-1 und du eine Länge von 5 hast dann läuft deine Schleife 5 mal durch nämlich von 0 bis 4. Somit bekommst du eine Exception, da beim 4. Index get(4+1) out of range ist. Wenn du nur bis zum vorletzten Element gehen willst dann musst du das = wegmachen. Somit gehen deine Indizes von 0 bis 3. Also: x < bclist.size()-1
 
Und du machst zwar eine Schleife bis bcListe.size()-1 oder -2 aber du greifst ja in der Schleife auf eine andere ArrayList limV zu. Ist denn sicher dass die beide gleich lang sind ?
 
Das Problem ist folgendes: meine bcListe ist eine ArrayList mit Objekten (verschiedene Angaben, u.A. auch Länge, Breite, etc.). Da die Aufgabe ist, diese Objekte nach Volumen zu sortieren, habe ich eine zweite ArrayList programmiert
Java:
private static ArrayList<Double> limV = new ArrayList<>();
die als nur double-Werte aufnimmt, wo ich dann auch die Werte von bcListe reinschreibe, die ich eben brauche
Java:
double volumen  = breite*hoehe*laenge;
limV.add(volumen);
(Breite, Höhe, Länge wird im Rahmen von bcListe per Zufall kreiert.

So nun wieder zurück: vielen Dank Robert für den Hinweis, ist gefixt und scheint zu klappen. Nur jetzt kommt eine weitere Exception und zwar in der if-Schleife? Irgendwie scheint es ein Problem mit limV.remove (x+1) zu geben. Wahrscheinlich aus den gleichen Gründen (weil es das nicht gibt), aber
wie kann ich das elegant lösen? Nochmal eine If-Schleife einbauen, und abfragen, ob x = 0 ist und
dann eben nicht mehr vergleichen? Oder gibt es dafür ein einfaches Kommando? Vielen Dank

Code:
java.lang.IndexOutOfBoundsException: Index: 3, Size: 3
    at java.util.ArrayList.rangeCheck(ArrayList.java:653)
    at java.util.ArrayList.remove(ArrayList.java:492)
    at Beleg_SS_2016.BaustelleEinrichten.sortieren(BaustelleEinrichten.java:70)
    at Beleg_SS_2016.__SHELL6.run(__SHELL6.java:5)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at bluej.runtime.ExecServer$3.run(ExecServer.java:730)
 
limV.remove(x);
limV.remove(x+1);

Jedes mal wenn du ein Element löschst rutschen die anderen nach. Wenn du jetzt das letzte mal in deiner for Schleife bist dann hast du noch 2 Elemente. Du löschst das vorletzte und das letzte rutscht nach. Damit ist x+1 nicht mehr in deiner liste da es nachgerutscht ist.
Ich würde dir zum tauschen die Collections.swap Methode empfehlen. Der gibst du einfach deine liste und x und y (x+1) als Parameter mit.

Googel einfach mal danach 🙂

PS: sowas wie if schleifen gibt es nicht 😉

Gruß Robert
 
Edit: So mit der Collections.swap Methode bin ich nun endlich einen Schritt weiter! 🙂

Aber ich habe immer noch einen komischen Fehler in der if-Abfrage
Java:
java.lang.IndexOutOfBoundsException: Index: 4, Size: 4
    at java.util.ArrayList.rangeCheck(ArrayList.java:653)
    at java.util.ArrayList.get(ArrayList.java:429)
    at Beleg_SS_2016.BaustelleEinrichten.sortieren(BaustelleEinrichten.java:62)
    at Beleg_SS_2016.__SHELL5.run(__SHELL5.java:5)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at bluej.runtime.ExecServer$3.run(ExecServer.java:730)

Wie kann ich das unterbinden? Ich will ja, dass der die einzelnen Werte durchgeht. Vielleicht ein Else einbauen? Oder wäre dafür z.B. eine while-Schleife besser? (damit es nicht abbricht wg. der Exception?)

2. Frage: es geht hier um diese Zeile

Java:
int x = 0;x<bcListe.size();x++){

Ich würde gerne bcListe.size()*bcListe.size() programmieren (also ein Vielfaches, vgl. mit der !-Funktion auf dem Taschenrechner, Bsp: bcListe hat 4 Elemente, also soll das ganze 4x4= 16 mal durchlaufen werden). Gibt es dafür einen Trick? Oder einen math. Javaausdruck?

Nachtrag: Ich meinte If-Abfrage, nicht Schleife Robat ;-))
 
Zuletzt bearbeitet:
Wie kann ich das unterbinden? Ich will ja, dass der die einzelnen Werte durchgeht. Vielleicht ein Else einbauen? Oder wäre dafür z.B. eine while-Schleife besser? (damit es nicht abbricht wg. der Exception?)
Indem du in der for-schleife die passende Bedingung angibst 😉

Deine Schleife läuft bis size-1 (da du <0 nutzt), du greifst auf index+1 zu (also size), der höchste Index der Liste ist aber size-1.
 
Vielleicht verstehe ich dich ja völlig falsch aber warum schreibst du dann nicht:
Code:
int x = 0;x<bcListe.size()*bcListe.size();x++){
 
Vielleicht verstehe ich dich ja völlig falsch aber warum schreibst du dann nicht:
Code:
int x = 0;x<bcListe.size()*bcListe.size();x++){
Habe ich jetzt auch so programmiert. Wusste nicht, dass das so einfach geht ;-)

@mrBrown : verstehe ich leider nicht :-(( Ich rede von der If-Abfrage wo ich eine Exception kriege. Die for-Schleife ist schon repariert. Hier der neue Code:

Java:
 for (int x = 0;x<bcListe.size()*bcListe.size();x++){
       
            if (limV.get(x) > limV.get(x+1) ){
               
                System.out.println(x + ". Stelle " + limV.get(x));
                System.out.println(x+1 + ". Stelle " + limV.get(x+1));
               
                limV2=limV.get(x);
                limV3=limV.get(x+1);
               
                Collections.swap(limV,x,x+1);
              
               
                for (int z = 0;z<bcListe.size();z++){
           
          
                 System.out.println(limV.get(z));
           
        }
       
              
             
               
           
               
            }
        
          
           
           
        
 
  
        }
 
@mrBrown : verstehe ich leider nicht :-(( Ich rede von der If-Abfrage wo ich eine Exception kriege. Die for-Schleife ist schon repariert. Hier der neue Code:
Das der Code geändert ist kann ich ja schlecht erraten 😉

Gleiches Problem, du greifst auf Schleifen-Index+1 zu, was größer als der größte Listenindex ist, du musst die Bedingung anpassen, das die Schleife schon eins vorher beendet wird, am einfachsten mit einem -1
 

Zurück
Oben