Binäres Einfügen

Status
Nicht offen für weitere Antworten.

Pfaeff

Aktives Mitglied
Hallo,

Ich bin momentan echt am verzweifeln ;) Ich habe eine Klasse, die von LinkedList erbt und Elemente beinhaltet, die einen String (name) in ihren Attributen haben. Jetzt würde ich diese Liste gerne sortiert halten, sprich: ich mache beim Einfügen eine Binärsuche und merke mir den Wert, wo mein Element hinkommen soll. Zurückgeben möchte ich, ob das Element gefunden wurde. Ich war jetzt schon so weit, dass ich (nur zu Testzwecken) von einer Binärsuche auf eine lineare Suche umgestiegen bin, jedoch kommt bei mir immer das selbe Ergebnis (ganz glücklich bin ich mit der Implementierung ohnehin nicht):
Java:
import java.util.LinkedList;

public class GroupList extends LinkedList<ObjGroup> {
    private int index = 0;
    public boolean find(String str) {
        for (int i=0; i<this.size(); i++) {
            index = i;
            int cmp = str.compareTo(this.get(i).name);
            if (cmp == 0)
                return true; 
            if (cmp < 0) 
                return false;                
        }    
        return false;        
    }
    // Einfügen nachdem sortiert wurde
    public boolean add(ObjGroup group) {
        index = Math.max(Math.min(index, this.size()), 0);
        super.add(index, group);
        return true;
    }    
    // Gesuchtes Element zurückgeben
    public ObjGroup getGroup() {
        if ((index >= 0) && (index < this.size()))
            return this.get(index);
        return null;
    }
}
Meine Beispieleingabe folge (mit jeweiligem Aufruf von find()) sieht so aus:
a d c b f
Die Ausgabe lautet dann: b c d f a statt a b c d f. Ich denke mir mal, dass die Art wie ich mir meinen index merke nicht ganz richtig ist.

EDIT: Ich glaube mit Comparator und Collections lässt sich da vielleicht was machen, aber ich bekomme es grad nicht hin ;)

Vielen Dank,
mfg
 
Zuletzt bearbeitet:
S

SlaterB

Gast
niemals sollte eine Methode, die nicht vom Namen her direkt dafür zuständig ist, einen Wert setzen und eine andere ihn dann benutzen,
add() sollte auch funktionieren ohne dass man vorher find() aufruft,
was passiert gar wenn man find() mit anderem Objekt aufruft? Chaos

-------
find() sieht bisher auch noch nicht aus,
aber das wußtest du wohl nach der Ausgabe,
baue doch logging ein, zu Beginn der Methode gibst du den Suchtwert + den Inhalt der Liste aus,
schaust dir die Vergleiche in der Schleife im Detail an und den Index am Ende, und prüfst mit deinem Kopf, ob das so korrekt ist oder nicht,
wenn du den Fehler erkannt hast und dich immer noch fragst, wie man das korrigieren kann, dann können wir ja nochmal drüber reden

ständig get(i) aufzurufen ist ziemlich schlecht bei LinkedList, da wird immer von Element 0 an neu alle Elemente durchlaufen,
lieber einen Iterator verwenden,
aber du wolltest wohl eh ganz was anderes,

Binärsuche im Sinne von Intervalhalbierung (erst mit Element an Position size/2 vergleichen usw.) könntest du direkt in deine Methode einbauen

Comparator oder Comparable wäre bei eigener Implementation nicht so viel anders, ob nun string.compare(string) oder ObjGroup.compare(ObjGroup),
für APIs wäre das natürlich interessant, Collections.sort() scheint übertrieben, jedes mal komplett neu sortieren?
dann schon lieber eine Struktur, die selber beim Einfügen sortiert, SortedList/ SortedLinkedList gibts aber nicht..
 

Pfaeff

Aktives Mitglied
Ja genau das mit der Variable war das was ich meinte das mir überhaupt nicht gefällt ;)
Ich muss halt irgendwie rausfinden können, ob etwas gefunden wurde, damit ich unterscheiden kann, ob ich beim Index einfügen muss, oder nicht.
Ich bin den Algorithmus (auch den mit der Intervalhalbierung) schon mehrfach schrittweise durchgegangen und bin auch auf die selben Ergebnisse gekommen wie mein Algorithmus. Allerdings bin ich noch nicht dahinter gekommen, warum es nicht funktioniert.
Angenommen es ist ein Element drin, so wird der Suchindex nicht größer als 0 werden. Wenn ich aber ein Element einfügen möchte, das größer ist, so brauche ich eine 1.

Das mit dem Iterator ist ein guter Tipp, danke ;)
 
S

SlaterB

Gast
genau, wenn der Index gleich der Size der Liste-1 ist musst du z.B. am Ende nochmal mit dem letzten Element vergleichen und den Index gegebenenfalls um 1 erhöhen,
nur in der Schleife kann der höchste Index nicht erreicht werden
 

Pfaeff

Aktives Mitglied
so kommt es immerhin schon fast hin:
Java:
    public int find(String str) {
        int start = 0;
        int end = this.size()-1;
        int index = 0;
        String tmp = new String();
        while ((end-start) >= 0) {
            index = start + (end-start)/2;
            tmp = this.get(index).name; 
            if (tmp.compareTo(str) < 0)
                start = index+1;
            if (tmp.compareTo(str) > 0)
                end = index-1;     
            if (tmp.equals(str))
                return index;                
        }
        if (index == this.size()-1)
            index++;
        return index;
    }
Aber scheinbar gibt es noch Fälle (vielleicht wenn das gesuchte Element kleiner ist als das Letzte), wo es nicht geht. So klappt es auch nicht:
Java:
// Das letzte Element überprüfen
        if (index == this.size()-1) {
            int c = this.get(this.size()-1).name.compareTo(str);
            if (c < 0) {
                index++;
            } else {
                index--;
            }
        }
Und wie gebe ich zurück, ob das Element nun gefunden wurde? Wäre schlecht, wenn ich zweimal hintereinander suchen müsste.
 
Zuletzt bearbeitet:
S

SlaterB

Gast
niemals new String() schreiben,
String tmp = "";
oder
String tmp = null;
geht genauso

und immer noch mein Rat:
baue doch Logging ein, zu Beginn der Methode gibst du den Suchwert + den Inhalt der Liste aus,
schaust dir die Vergleiche in der Schleife im Detail an und den Index am Ende, und prüfst mit deinem Kopf, ob das so korrekt ist oder nicht,
ich könnte das auch und dann korrigieren,
aber mir scheint, du solltest das selbst versuchen wenn du schon derart gewagtes programmierst
 

Pfaeff

Aktives Mitglied
danke, so scheint es zu gehen:
Java:
    public int find(String str) {
        if (this.size() == 0)
            return 0;
        int start = 0;
        int end = this.size()-1;
        int index = 0;
        String tmp = "";
        int c = 0;
        while ((end-start) >= 0) {
            index = start + (end-start)/2;
            tmp = this.get(index).name; 
            c = tmp.compareTo(str);
            if (c < 0)
                start = index + 1;
            if (c > 0)
                end = index - 1;     
            if (c == 0)
                return index;                
        }
        tmp = this.get(index).name;
        c = tmp.compareTo(str);
        if (c < 0)
            index++;  
        return index;
    }
Wie gesagt ist jetzt noch die Frage, wie ich zusätzlich ausgeben kann, ob das Element gefunden wurde. Die einzige Möglichkeit die mir einfiele, wäre eine neue Klasse zu definieren, die einen int und einen boolean beinhaltet.

mfg
 
S

SlaterB

Gast
stimmt, mit einem Rückgabewert ist man da begrenzt,

wenn man aber erstmal den Index hat, kann man auch relativ zügig in einem zweiten Schritt das Element zum Index laden und dessen Name anschauen
 
S

SlaterB

Gast
kommt auf den Aufwand eines Vergleichs an ;)

vielleicht ist auch die Verlinkung gerade in Intervall-Halbierungs-Schritten ;)
 

Pfaeff

Aktives Mitglied
Lineare Suche hat doch O(n) und die binäre Suche O(log n), nur dass ich bei der binären zusätzlich beim Einfügen suchen muss (bzw nichtmal das, weil ich ja die Werte der Suche direkt fürs Einfügen benutzen kann).
Sollte sie tatsächlich langsamer sein (durch die Listeneigenschaft), kann ich mir die Sortiererei auch sparen ;)
 
Zuletzt bearbeitet:

Civilazi

Bekanntes Mitglied
Lineare Suche hat doch O(n) und die binäre Suche O(log n),
Das gilt aber nur, wenn du Random Access hast, z.B. bei Arrays. Wenn du bei der LinkedList aber mit get(i) auf ein Element auf nem Index zugreifst, läuft er von vorne bis i komplett durch, wie soll er auch anders, das ist halt "nur" ne doppelt verkettete Liste. Das machst du im Zweifel mehrmals, vor allem, wenn das gesuchte in der rechten Hälfte ist, machst du da schon mehr Vergleiche als wenn du einfach einmal durchläufst. Befindet sich das gesuchte in der linken Hälfte, hast du aber auch kein O(logn). Eine LinkedList ist für sowas einfach nicht gedacht. Wenn du eine Datenstruktur brauchst, die in O(logn) Sachen sortiert bereitstellt mit entsprechenden add, poll etc.-Methoden, nimm eine PriorityQueue. Wenn du es selbst machen willst, dann eine ArrayList.
 

Pfaeff

Aktives Mitglied
Es würde also reichen LinkedList durch ArrayList zu substituieren um den gewünschten Geschwindigkeitsboost zu erreichen? Was ist genau der Unterschied bei einer ArrayList? Bzw. was ist der Vorteil der LinkedList?

EDIT: mein Programm ist nun um das 100 fache schneller, danke ;)

mfg
 
Zuletzt bearbeitet:

Landei

Top Contributor
Array: Feste Länge, muss bei der Erzeugung angegeben werden.
ArrayList: Variable Länge, wächst mit den Daten
 

Civilazi

Bekanntes Mitglied
Es würde also reichen LinkedList durch ArrayList zu substituieren um den gewünschten Geschwindigkeitsboost zu erreichen? Was ist genau der Unterschied bei einer ArrayList? Bzw. was ist der Vorteil der LinkedList?

EDIT: mein Programm ist nun um das 100 fache schneller, danke ;)

mfg

Da gibts es hier sogar ein How To: Welche Collection wann verwenden? oder so in den FAQs.
Mal ganz kurz: Arrays sind toll (Random Access), habern aber eine feste Größe, die man bei der Erstellung angeben muss. Eine LinkedList ist toll (dynamische Größe, jeder Eintrag kennt seinen Vordermann und den nächsten Eintrag, die Liste selber den Anfang und das Ende, dadurch kann man die ganze Liste durchlaufen), die kann man nehmen, wenn man noch nicht weiß, wieviel Sachen man speichern will, aber dann immer alles durchlaufen und irgendwas damit tun will. Eine ArrayList ist auch toll (verwaltet im Hintergrund ein Array, das wenn es zu klein wird, in ein neues größeres kopiert wird <-- kostet Zeit), sollte man also verwenden, wenn man eigentlich ein Array mit Indexzugriff will, aber noch nicht weiß, wieviel Datensätze man hat, oder sich das ändern kann.
Collections kennen lohnt sich, auch Vector hat seine Berechtigung, PriorityQueue, Maps, ...

EDIT: Aber schön, dass es geholfen hat =)
 
Zuletzt bearbeitet:

Pfaeff

Aktives Mitglied
Ich habe halt sehr viele Daten und weiß vorher nicht wie viele und muss häufig add() benutzen und ab und an auch get(). Durch-iterieren geht leider nicht und Löschen muss ich nichts, also denke ich, dass die ArrayList wohl die beste Wahl ist.

danke
 

Civilazi

Bekanntes Mitglied
Ich habe halt sehr viele Daten und weiß vorher nicht wie viele und muss häufig add() benutzen und ab und an auch get(). Durch-iterieren geht leider nicht und Löschen muss ich nichts, also denke ich, dass die ArrayList wohl die beste Wahl ist.

Meiner Meinung nach wäre die beste Wahl immer noch eine PriorityQueue, weil die schon tut, was du noch implementieren musstest.
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
T Binäres Problem! Java Basics - Anfänger-Themen 3
D Binäres Suchen Java Basics - Anfänger-Themen 11
C Binäres Suchen mit Rekursion Java Basics - Anfänger-Themen 5
Hilde22 Neu Start JButton einfügen Java Basics - Anfänger-Themen 2
Nitrogames Variablen Variable aus JOptionPane Abfrage in Array einfügen Java Basics - Anfänger-Themen 4
melaniemueller setCharAt Leerzeichen zusätzlich einfügen Java Basics - Anfänger-Themen 8
S Algorithmus Datensätze einfügen wenn... Java Basics - Anfänger-Themen 26
E In Array Werte einfügen? Java Basics - Anfänger-Themen 5
districon Element in Liste einfügen Java Basics - Anfänger-Themen 1
Y Einfügen in eine doppelt verkettete Liste Java Basics - Anfänger-Themen 8
Gaudimagspam Attribute einfügen private Java Basics - Anfänger-Themen 3
marcooooo Separator zwischen allen Zeichen eines Strings einfügen Java Basics - Anfänger-Themen 29
R Inventar und Items auf ein 2D ArrayFeld einfügen Java Basics - Anfänger-Themen 2
S Bild einfügen // NEU Java Basics - Anfänger-Themen 12
S Datenbank Tabelle eine Zeile an einer bestimmten Stelle einfügen Java Basics - Anfänger-Themen 2
V_Fynn03 Erste Schritte Einen Wert in ein TextField einfügen aus einer anderen Klasse Java Basics - Anfänger-Themen 3
E Datentypen Einfügen von Objekten in eine Map Java Basics - Anfänger-Themen 2
O Naives links rechts einfügen in ADT Baum Java Basics - Anfänger-Themen 8
O BinärBaum einfügen Java Basics - Anfänger-Themen 13
M Sqlite table löschen und daten einfügen Java Basics - Anfänger-Themen 5
M Erste Schritte Mit Variable verschiedene Texte in Textfeld einfügen Java Basics - Anfänger-Themen 27
M Klasse in JTable einfügen Java Basics - Anfänger-Themen 7
J In einer Klasse ein AlertDialog einfügen Java Basics - Anfänger-Themen 4
S Elemente in Liste einfügen Java Basics - Anfänger-Themen 2
S Interface (WindowBuilder) Panels in einen Frame einfügen Java Basics - Anfänger-Themen 10
x-tshainge Java Bilder einfügen Java Basics - Anfänger-Themen 1
T Variablen “ in String einfügen Java Basics - Anfänger-Themen 1
Orkanson Objekte in ein Array einfügen Java Basics - Anfänger-Themen 5
S Doppelte Liste Einfügen Java Basics - Anfänger-Themen 1
X Objekte in ArrayList einfügen Java Basics - Anfänger-Themen 10
jaleda100 JTextArea Zeile einfügen Java Basics - Anfänger-Themen 1
R Spielfeldbegrenzung einfügen (Java)? Brauche Hilfe! Java Basics - Anfänger-Themen 15
D B-Baum einfügen und löschen Java Basics - Anfänger-Themen 2
S Einfach verkettete Liste Element an bestimmter Position einfügen Java Basics - Anfänger-Themen 24
JavaNewbie2.0 Tausende Wörter in Arrays automatisch einfügen Java Basics - Anfänger-Themen 10
J Wie kann ich Images per Tastendruck anzeigen/einfügen? Java Basics - Anfänger-Themen 3
F In LinkedList einen Wert ersetzen oder neu einfügen Java Basics - Anfänger-Themen 7
C Verkettete Liste - sortiert einfügen Java Basics - Anfänger-Themen 7
J Scroll-Leiste einfügen Java Basics - Anfänger-Themen 12
U Sound einfügen Java Basics - Anfänger-Themen 6
P String zerstückeln und in Excel einfügen Java Basics - Anfänger-Themen 11
J Objecte in TreeSet einfügen klappt nicht Java Basics - Anfänger-Themen 5
P Variablen Wie kann ich eine lokale Variable in eine andere Methode einfügen? Java Basics - Anfänger-Themen 27
S Bild einfügen Java Basics - Anfänger-Themen 16
D Taschenrechnerereignisse einfügen Java Basics - Anfänger-Themen 18
B Vererbung In offener Hash Tabelle einfügen Java Basics - Anfänger-Themen 4
W Listenelement einfügen Java Basics - Anfänger-Themen 9
P OOP Eingabevariablen der Klasse Raum in der Methode addEvent ans Ende einer ArrayList einfügen Java Basics - Anfänger-Themen 3
8 Eigenes Bild in email einfügen Java Basics - Anfänger-Themen 1
D Datenbankzugriff - Leere Zeile einfügen Java Basics - Anfänger-Themen 2
GadgetSofa IOException fehlt aber wo einfügen? Java Basics - Anfänger-Themen 6
K JTable Bild einfügen Java Basics - Anfänger-Themen 1
A Objekte in eine Liste einfügen Java Basics - Anfänger-Themen 7
J Methoden Einfügen von Objekten nach Alphabet in ArrayList funktioniert nicht Java Basics - Anfänger-Themen 2
S jList --> Array einfügen und Liste löschen Java Basics - Anfänger-Themen 5
J Buchstabe (char) an zufällige Position eines Strings einfügen Java Basics - Anfänger-Themen 1
C Kalender in Applet einfügen Java Basics - Anfänger-Themen 0
M JFrame Bild einfügen Java Basics - Anfänger-Themen 3
D Bild in Frame einfügen Java Basics - Anfänger-Themen 11
F Collections Sortierung und Einfügen von Elementen Java Basics - Anfänger-Themen 1
K Erste Schritte Classe in andere Einfügen?? Java Basics - Anfänger-Themen 12
P Klasse in Klasse einfügen (arrayliste) Java Basics - Anfänger-Themen 7
F Bibliotheken einfügen ??? Java Basics - Anfänger-Themen 2
P Hintergrundbild in Swing einfügen Java Basics - Anfänger-Themen 3
T HashMap Werte einfügen, durchsuchen und auslesen Java Basics - Anfänger-Themen 17
K JTextField in ein Spiel einfügen Java Basics - Anfänger-Themen 2
Q Erste Schritte In CharArrayWriter Zeichen an Stelle einfügen Java Basics - Anfänger-Themen 4
J Daten in eine JList einfügen Java Basics - Anfänger-Themen 6
J Neue Zeile an bestimmter Stelle in Textdatei einfügen Java Basics - Anfänger-Themen 2
D Durch Button klick wert in JTextField einfügen Java Basics - Anfänger-Themen 5
J Button in extra Klasse festlegen und in anderer Klasse einfügen? Java Basics - Anfänger-Themen 3
J GUI Button Klasse in anderer Klasse einfügen Java Basics - Anfänger-Themen 3
E HILFE Projekt für die Schule--> Bilder einfügen Java Basics - Anfänger-Themen 9
D 2 Fragen: Position ändern vs. LayoutManager / Bilder einfügen im Vordergrund Java Basics - Anfänger-Themen 3
D String aus txt in label für Tabelle einfügen Java Basics - Anfänger-Themen 8
A Aktuelles Datum einfügen.. Java Basics - Anfänger-Themen 4
I fertige xml-datein in eine noch aufzubauende xml-datei einfügen Java Basics - Anfänger-Themen 4
N JTable - Zellfarben ändern, GUI-Komponenten in Zellen einfügen Java Basics - Anfänger-Themen 5
B Ordner in jar dateien einfügen Java Basics - Anfänger-Themen 4
S Erste Schritte Bluej Automatisches Einfügen von Objekten Java Basics - Anfänger-Themen 4
A String aus anderer Klasse in JTextArea einfügen Java Basics - Anfänger-Themen 7
J Bild einfügen Java Basics - Anfänger-Themen 3
S Musik einfügen funktioniert noch nicht Java Basics - Anfänger-Themen 6
K paint() mit einfügen Java Basics - Anfänger-Themen 14
A Sortiertes Einfügen in Liste Java Basics - Anfänger-Themen 2
B org.apache.commons.... Folder in Projekt einfügen Java Basics - Anfänger-Themen 6
Kenan89 String in ObjectList einfügen Java Basics - Anfänger-Themen 2
H Bilder im GUI einfügen Java Basics - Anfänger-Themen 12
A SwingX in Eclipse einfügen Java Basics - Anfänger-Themen 5
B Einfügen von Dateien Java Basics - Anfänger-Themen 10
M Java String " einfügen Problem Java Basics - Anfänger-Themen 2
M Video in ClassLoader einfügen Java Basics - Anfänger-Themen 7
S Itext und eine neue Zeile einfügen Java Basics - Anfänger-Themen 2
P JPanel in JTable einfügen Java Basics - Anfänger-Themen 23
D Werte aus Excel in Diagramm einfügen Java Basics - Anfänger-Themen 6
K Fehler beim Einfügen eines Programm Icons Java Basics - Anfänger-Themen 6
Binary.Coder Vor und nach jeder Codezeile etwas einfügen Java Basics - Anfänger-Themen 3
A Problem beim einfügen in eine Datenbank Java Basics - Anfänger-Themen 2
D Input/Output Zeilen aus txt-datei in Java-Liste einfügen Java Basics - Anfänger-Themen 9
J JPG in einem Label einfügen und anzeigen lassen Java Basics - Anfänger-Themen 2

Ähnliche Java Themen

Neue Themen


Oben