Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
faecher:informatik:oberstufe:adt:set:implementationen:start [14.11.2021 19:16] – [Variante 3: Hashtable] sbel | faecher:informatik:oberstufe:adt:set:implementationen:start [Unbekanntes Datum] (aktuell) – gelöscht - Externe Bearbeitung (Unbekanntes Datum) 127.0.0.1 | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
- | ====== Die Set-Implementationen im Detail ====== | ||
- | ===== Variante 1: ArrayList ===== | ||
- | |||
- | Die einfachste Lösung ist, wenn der ADT Set als interne Datenstruktur eine '' | ||
- | Beim Einfügen muss immer getestet werden, ob der Wert bereits in der '' | ||
- | |||
- | ==== Bewertung ==== | ||
- | |||
- | |||
- | === Vorteile: === | ||
- | |||
- | * Einfache Implementation | ||
- | * Speicherbedarf relativ gering (etwa proportional zur Anzahl der Werte) | ||
- | |||
- | |||
- | === Nachteile: === | ||
- | * Suche nach einem Element bei großen Mengen aufwendig (proportional zur Anzahl der Werte) | ||
- | |||
- | ===== Variante 2: Bitvektor ===== | ||
- | |||
- | Man kann eine Menge von Integer-Zahlen auch in eine einzelne Integer-Zahl verpackt darstellen, indem man die entsprechenden Bits in ihrer Binärdarstellung setzt. Man spricht dann von einem **Bitvektor**. | ||
- | |||
- | **Beispiel: | ||
- | |||
- | {{ : | ||
- | |||
- | Da eine Integer-Zahl in Java 32 Bit lang ist, kann man mit einer Integer-Zahl also für die Zahlen von 0 bis 31 darstellen, ob sie in einer Menge enthalten sind oder nicht. | ||
- | |||
- | ==== Ist eine Zahl in der Menge enthalten? ==== | ||
- | |||
- | Um herauszufinden, | ||
- | |||
- | <code java> | ||
- | int vier_gesetzt = 25 & 16; // Ergebnis: 16 | ||
- | int eins_gesetzt = 25 & 2; // Ergebnis: 0 | ||
- | </ | ||
- | |||
- | {{ : | ||
- | |||
- | Der binäre UND-Operator verknüpft zwei '' | ||
- | |||
- | Eine Zahl ist in der Menge enthalten, wenn bei der UND-Verknüpfung ein Wert herauskommt, | ||
- | |||
- | ==== Zahlen hinzufügen ==== | ||
- | |||
- | |||
- | Um einen Wert zu einem Bitvektor hinzufügen, | ||
- | |||
- | **Beispiel: | ||
- | <code java> | ||
- | | ||
- | </ | ||
- | {{ : | ||
- | |||
- | Der binäre ODER-Operator verknüpft zwei '' | ||
- | |||
- | Beim Setzen eines Bits muss nicht geprüft werden, ob es bereits gesetzt ist – der ODER-Operator verändert in diesem Fall den Bitvektor nicht. | ||
- | |||
- | ==== Bitmasken ==== | ||
- | |||
- | Zum lesen und setzen von Elementen benötigt man die entsprechenden Zahlen, letztlich in Binärdarstellung. Diese Zahlen, die man zum Auslesen oder Setzen von Bits verwendet werden als '' | ||
- | |||
- | Eine Maske, bei der als niederwertigstes Bit nur das n-te Bit von rechts gesetzt ist, entspricht der Zahl 2< | ||
- | |||
- | In Java wird eine solche Bitverschiebung ("bit shift" | ||
- | |||
- | <code java> | ||
- | int y = 1 << 7; // y ist 1*27 = 128 | ||
- | </ | ||
- | |||
- | Man kann auch andere Zahlen als die 1 verschieben: | ||
- | |||
- | <code java> | ||
- | int x = 13 << 3; // x ist 13*23 = 104 | ||
- | </ | ||
- | |||
- | {{ : | ||
- | |||
- | ==== Zahlbereichserweiterung ==== | ||
- | |||
- | Mit einer einzelnen 32-Bit-Zahl kann man Mengen der Zahlen 0 bis 31 abbilden. Will man größere Werte erlauben, benötigt man eine ArrayList von Integer-Zahlen. | ||
- | |||
- | Die k-te Zahl der ArrayList repräsentiert damit die Elemente mit den Werten 32·k bis 32·k+31. | ||
- | |||
- | {{ : | ||
- | |||
- | Das Element '' | ||
- | |||
- | Beim Einfügen muss die ArrayList ggf. um Elemente erweitert werden, so dass sie groß genug ist. | ||
- | |||
- | Pseudocode: | ||
- | |||
- | < | ||
- | einfuegen(n: | ||
- | k = n / 32 | ||
- | solange Länge von daten ≤ k: | ||
- | hänge 0 an daten an | ||
- | bit = n % 32 | ||
- | maske = 1 << bit | ||
- | daten[bit] = daten[bit] | maske | ||
- | </ | ||
- | |||
- | ==== Bewertung ==== | ||
- | |||
- | |||
- | === Vorteile: === | ||
- | |||
- | * Sehr speichereffizient, | ||
- | * Lesender Zugriff in konstanter Anzahl von Schritten möglich | ||
- | * Schreibender Zugriff meistens schnell möglich | ||
- | |||
- | === Nachteile: === | ||
- | |||
- | * Wenn nur wenige, aber große Werte gespeichert werden, wird Speicher verschwendet | ||
- | * Konzept ist nur zum Speichern von Integer-Zahlen anwendbar | ||
- | |||
- | |||
- | ===== Variante 3: Hashtable ===== | ||
- | |||
- | Die Hashtable verwendet ein Array, das die Werte der Menge enthält. | ||
- | |||
- | Das Problem ist, dass die Suche nach einem Wert unter Umständen sehr lange dauert – insbesondere, | ||
- | |||
- | Die Idee des Hashings ist, dass man einem Wert " | ||
- | Wir nehmen als erstes Beispiel ein Array mit 10 Plätzen: | ||
- | |||
- | {{ : | ||
- | |||
- | Um den Speicherort eines Wertes '' | ||
- | '' | ||
- | < | ||
- | einfuegen(42) → Position 42 mod 10 = 2, daten[2] = 42 | ||
- | einfuegen(77) → Position 77 mod 10 = 7, daten[7] = 77 | ||
- | </ | ||
- | |||
- | {{ : | ||
- | |||
- | Um herauszufinden, | ||
- | |||
- | < | ||
- | enthaelt(42) → Position 42 mod 10 = 2, daten[2] == 42 → ja | ||
- | enthaelt(23) → Position 23 mod 10 = 3, daten[3] ist leer → nein | ||
- | enthaelt(17) → Position 17 mod 10 = 7, daten[7] != 17 → nein | ||
- | </ |