Algorithmen und Datenstrukturen 22. März 2018 B3. Verkettete Listen und Bäume Algorithmen und Datenstrukturen B3. Verkettete Listen und Bäume B3.1 Einführung Marcel Lüthi and Gabriele Röger B3.2 Verkettete Liste Universität Basel 22. März 2018 B3.3 Bäume M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 1 / 43 M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 2 / 43 B3. Verkettete Listen und Bäume Einführung B3. Verkettete Listen und Bäume Einführung Abstrakter Datentyp / Datenstruktur B3.1 Einführung Abstrakter Datentyp Eine Menge von Werten und Operationen, die auf dieser Menge definiert sind. Repräsentation und Implementation bleibt abstrakt. ADT kann mittels verschiedener Datenstrukturen implementiert sein. Datenstruktur Beschreibt wie die Daten organisiert sind Implementation und Repräsentation explizit Organisation so ausgelegt, dass gewisse Operationen effizient ausgeführt werden können. Dieselbe Datenstruktur kann in verschiedenen ADTs benutzt werden. Derselbe Begriff (Beispiel Array) kann sowohl für Datenstruktur als auch Datentyp stehen. M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 3 / 43 M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 4 / 43
B3. Verkettete Listen und Bäume Einführung Wiederholung: Multimengen, Warteschlangen und Stapel B3. Verkettete Listen und Bäume Einführung Wissenschaftler des Tages Multimenge Ungeordnet Stapel LIFO Warteschlange FIFO Nobelpreisträger und Gewinner des Turing Awards Pionier in künstlicher Intelligenz Erfinder der verketteten Liste (im Rahmen der IPL Sprache). Simon (Ökonom) Herbert Newell, Allen, and Fred M. Tonge. An introduction to information processing language V. Communications of the ACM (1960). M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 5 / 43 M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 6 / 43 Motivation B3.2 Verkettete Liste Arrays sind nicht flexibel genug Brauchen immer grossen, kontinuierlichen Block an Speicher Einfügen ist teuer (vor allem am Anfang) Enqueue oder Dequeue in Warteschlange hat Komplexität O(n) Lösung muss uns erlauben Elemente im Speicher zu verteilen. M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 7 / 43 M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 8 / 43
Listen Listen Wie kann man Elemente ordnen die verteilt im Speicher sind? Eine Liste ist eine geordnete Kollektion von n Elementen (n N 0 ) Array: Ordnung kommt von Anordnung in Speicher M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 9 / 43 M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 10 / 43 Verkettete Listen Quiz: Komplexität Array / Verkettete Liste Wichtige, flexible Datenstruktur Jeder Knoten speichert sein Datum, sowie eine Referenz (Zeiger) auf Nachfolger Ende muss speziell gekennzeichnet werden (häufig null/none).... oder wir brauchen Referenz auf letztes Element Operation Array Verkettete Liste Zugriff auf beliebiges Element Einfügen, Löschen am Anfang Einfügen am Ende Löschen am Ende Einfügen, Löschen in Mitte Verschwendeter Speicher Take-home Message Verschiedene Datenstrukturen machen verschiedene Trade-offs M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 11 / 43 M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 12 / 43
Verkettete Listen: Datenstruktur Einfügen am Anfang class Node [ Item ]: } Beispiele: # Das gespeicherte Datum item : Item # Referenz auf den Nachfolger next : Node # Konstruktur : Erzeugen eines neuen Nodes Node ( item : Item, next : Node [ Item ]) Node( first, None) Node( first, Node( second, None)) Node( first, Node( second, Node( third, None)) M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 13 / 43 M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 14 / 43 Einfügen am Ende Weitere Operationen Einfach: Vom Anfang entfernen Traversieren Schwierig: Vom Ende entfernen An beliebiger Position einfügen An beliebiger Position entfernen Element an beliebiger Position lesen/schreiben Einfach/Schwierig bezieht sich auf Aufwand und nicht Implementation. M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 15 / 43 M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 16 / 43
Doppelt verkettete Liste Beispiele und Implementation Referenz nicht nur auf Nachfolger, sondern auch vorhergehendes Element Macht Entfernen vom Ende günstig. IPython Notebooks: LinkedList.ipnb M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 17 / 43 M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 18 / 43 Rekursive Definition Verkettete Listen: Datenstruktur (rekursiv) Eine Liste L ist die leere Liste oder ein Element H (Head) gefolgt von einer Liste: H, L class List [ Item ]: head : Item tail : List [ Item ] List ( head : Item, tail : List [ Item ]) emptylist = List ( None, None ) Gleich wie Definition mit Node - nur neue Namen: (Node List, item head, next tail) M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 19 / 43 M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 20 / 43
Verkettete Listen (rekursiv) Beispiele und Implementation Natürliche, rekursive Implementation vieler Operationen Implementation folgt Datenstruktur def printlist ( list ): if ( list == emptylist ): return "" else : return str ( list. head ) + printlist ( list. tail ) IPython Notebooks: LinkedList.ipnb M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 21 / 43 M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 22 / 43 Liste : ADT Liste : ADT Liste ist nicht nur Datenstruktur, sondern auch ADT class List [ Item ]: def getfirst : Item def getlast : Item def size () : int def isempty () : boolean def append ( item : Item ) def addfirst ( item : Item ) def insert ( item : Item, pos : int ) def exists ( item : Item ) : boolean def iterate () -> Iterator Viele weitere Operationen möglich. Design Entscheidung! Beispiel aus Java: https://docs.oracle.com/javase/7/ docs/api/java/util/list.html ADT erlaubt verschiedene Implementationen derselben Schnittstelle Beispiel aus Java LinkedList In Java: java.util.linkedlist sowie java.util.arraylist Achtung Verschiedene Listen haben dieselbe Schnittstelle, aber Operationen haben nicht dieselbe Komplexität. M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 23 / 43 M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 24 / 43
Was ist ein Baum Struktur um Daten hierarchisch anzuordnen. B3.3 Bäume Abbildung: http://www.ub.unibas.ch/bernoulli/index.php/stammbaum M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 25 / 43 M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 26 / 43 Was ist ein Baum Beispiele Rekursive Definition: Baum Ein Baum T der Ordnung n ist entweder der leere Baum, oder besteht aus einem Knoten (genannt Wurzel) sowie maximal n Bäumen (den Unterbäumen von T ). Nicht rekursive Definition in Teil über Graphen Eine Liste ist ein Spezialfall eines Baumes (Baum der Ordnung 1) M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 27 / 43 M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 28 / 43
Terminologie Wichtigster Spezialfall: Binärbaum Binärbaum (Binary Tree) Ein Binärbaum T ist entweder der leere Baum, oder besteht aus einem Knoten (genannt Wurzel) sowie maximal 2 Bäumen (den Unterbäumen von T ). Binärbäume haben jede Menge Anwendungen Unser aktueller Fokus M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 29 / 43 M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 30 / 43 Terminologie (2) Quiz Voller Binärbaum: Jeder Knoten hat 0 oder 2 Kinder Vollständiger (oder kompletter) Binärbaum: Alle Ebenen sind vollständig gefüllt ausser evtl. die letzte Ebene wobei nur Blätter rechts fehlen dürfen. Perfekter Binärbaum: Alle internen Knoten haben genau 2 Kinder und alle Blätter sind auf der gleichen Ebene Welche der folgenden Bäume sind voll, vollständig oder perfekt? Wie ist es mit dem leeren Baum? M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 31 / 43 M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 32 / 43
Höhe eines perfekten Binärbaums Höhe eines vollständigen Binärbaums Theorem Die Höhe eines perfekten Binärbaums der Grösse N (also mit N Knoten) ist log 2 (N + 1) 1. Beweis. Die Anzahl Knoten N eines perfekten Baumes der Höhe h sind N = 2 0 + 2 1 +..., +2 h = 2 h+1 1 Auflösen nach h ergibt log 2 (N + 1) = h + 1 h = log 2 (N + 1) 1 Theorem Die Höhe eines vollständigen Binärbaums der Grösse N is log 2 (N) Es stimmt für Höhe 0 (Für N = 1 ist log 2 (1) = 0) Die Höhe nimmt nur um 1 zu, wenn N so vergrössert wird, dass es eine Zweierpotenz wird. D.h ein Knoten ist alleine auf der letzten Ebene. M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 33 / 43 M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 34 / 43 Datenstruktur für Binärbaum class BinaryTree [ Item ]: item Item left : BinaryTree [ Item ] right : BinaryTree [ Item ] Traversierung Breitenansatz (breadth-first-search). Eine Ebene nach dem anderen. Tiefenansatz (depth-first-search). Zuerst in die Tiefe, dann links nach rechts. BinaryTree ( item : Item, left : BinaryTree [ Item ], right : BinaryTree [ Item ] ) emptytree = BinaryTree ( None, None, None ) Quelle:http://www.cse.unsw.edu.au/ billw/justsearch.html M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 35 / 43 M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 36 / 43
Depth-first-search Traversierung Implementation Wir unterscheiden drei Hauptarten der DFS Traversierung: Preorder Aktueller Knoten zuerst, danach weiter traversieren Inorder Aktueller Knoten zwischen Traversierung von Unterbäumen Postorder Aktueller Knoten nach Traversierung von Unterbäumen IPython Notebooks: Trees.ipynb M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 37 / 43 M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 38 / 43 ADT für Binärbaum? Teil ADT für Binärbau (nicht mutierend) Genau wie Listen, könnten wir einen Binärbaum als Abstrakten Datentyp definieren. Kein natürliches API um Einfügen der Elemente zu definieren Wo soll eingefügt werden Einfacher Datenstruktur abhängig zu definieren. Später: Kompletter ADT für Binärsuchbaum Einfügeposition wird anhand Ordnung der Elemente bestimmt Nicht mutierende Operationen können einfach definiert werden. class BinaryTree [ Item ]: def item () -> Item def left () -> BinaryTree def right () -> BinaryTree def depth () -> int def isleaf () -> bool def iterate ( order : Order ) -> Iterator M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 39 / 43 M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 40 / 43
Implementation mittels Array (1) Der ADT Binärbaum kann auch mittels Array implementiert werden. Linker Teilbaum: Index Wurzel * 2 Rechter Teilbaum: Index Wurzel * 2 + 1 Implementation mittels Array (2) Wechseln zwischen Ebenen ohne explizite Links (Kind / Elternknoten) möglich. Speichereffizient für vollständigen Binärbaum Sehr ineffizient wenn Baum zur Liste degenieriert (nur linke oder rechte Teilbäume) Wird beim Heap zur effizienten Implementation einer Vorrangswarteschlange (priority queue) ausgenutzt! Mehr dazu nächste Woche. Quelle: Abbildung 2.26, Algorithms, Sedgewick & Wayne M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 41 / 43 M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 42 / 43 Quiz Ist die verkettete Liste eine Datenstruktur oder ein ADT? Weshalb ist das Löschen des letzten Elements in einer verketteten Liste schwierig? Können wir beliebige Binärbäume mittels einem Array implementieren oder nur vollständige? Wie ist es mit Bäumen beliebiger Ordnung? Wie unterscheidet sich die Komplexität der Operation left des Binärbaum ADT in den verschiedenen Implementationen (Baum Datenstruktur / Array)? M. Lüthi, G. Röger (Universität Basel) Algorithmen und Datenstrukturen 22. März 2018 43 / 43