Präsentation herunterladen
Die Präsentation wird geladen. Bitte warten
Veröffentlicht von:Eberhard Nahrwold Geändert vor über 10 Jahren
1
Institut für Wirtschaftsinformatik – Software Engineering, JKU Linz 1 Algorithmen und Datenstrukturen SS 2005 Mag.Th. Hilpold u. Dr. A.Stritzinger Institut für Wirtschaftsinformatik- Software Engineering JKU Linz
2
Institut für Wirtschaftsinformatik – Software Engineering, JKU Linz 2 Inhalt l Lösung Übung 6 l Rekursion l Bäume, Binärbaume, Binäre Suchbäume l Vorbesprechung Übung 8
3
Institut für Wirtschaftsinformatik – Software Engineering, JKU Linz 3 Rekursion - Konzept Rekursion im allgemeinen bedeutet, daß sich etwas als Teil enthält oder mithilfe von sich selbst definiert ist. Veranschaulichung: Mathematische Definition der Fakultätsfunktion: fak(n) = n* fak(n-1); fak(0) = 1. Rekursive Algorithmen: Wenn eine Funktion, Prozedur oder Methode einen Aufruf von sich selbst enthält (= direkte Rekursion). Wenn eine Methode eine andere aufruft und diese wiederum die erste direkt oder indirekt ruft (= indirekte Rekursion)
4
Institut für Wirtschaftsinformatik – Software Engineering, JKU Linz 4 Rekursionsbedingungen Ein rekursiver Aufruf darf nicht die gleichen Parameterwerte erhalten, wie die aktuelle Ausführung, da dies zu einer endlos Rekursion führen würde. Statt dessen muß bei jedem rekursiven Aufruf, die durch die Parameter definierte Aufgabe etwas "kleiner" sein. Jeder rekursive Algorithmus muß eine Fallunterscheidung enthalten mit mindestens einem nicht rekursiven Zweig, der bei der Terminierung ausgeführt wird (kann u.U. leer sein). Bei jedem rekursiven Aufruf muß ein neuer Datensatz für alle lokalen Variablen und Parameter angelegt werden, der während der Algorithmusausführung, den darunterliegenden Datensatz verbirgt. Stack-verwaltete (Aktivierungs-) Datensätze sind in fast allen modernen Programmiersprachen üblich. Für praktische Anwendungen muß die Tiefe der Rekursion relativ klein sein.
5
Institut für Wirtschaftsinformatik – Software Engineering, JKU Linz 5 Beispiel: Fakultät berechnen int factorial( int n) { if (n>1) { return factorial(n-1) * n; } else { return 1; } trace: factorial(5), factorial(4), factorial(3), factorial(2), factorial(1) return 1 return 1*2 return 2*3 return 6*4 return 24*5 ergebnis: 120
6
Institut für Wirtschaftsinformatik – Software Engineering, JKU Linz 6 Rekursion vs. Iteration Die Falkultätsfunktion kann natürlich einfacher und effizienter iterativ berechnet werden int factorial( int n) { int result = 1; for (int i=2; i<=n; i++) { result = result * i; } return result; } Grundsätzlich gilt: Jeder rekursive Algorithmus kann auch iterativ (d.h. mittels Wiederholungs- aktionen) gelöst werden und umgekeht kann jede iterative Lösung in eine rekursive überführt werden. Rekursive Algorithmen eigenen sich besonders dann, wenn das zugrundeliegende Problem rekursiv definiert ist, oder wenn die Datenstrukturen rekursiv sind.
7
Institut für Wirtschaftsinformatik – Software Engineering, JKU Linz 7 Beispiel: Fibonacci-Funktion Leonardo Fibonacci (ital. Mathematiker, 12 Jhdt. Pisa) fand eine Reihe, welche angeblich die Populationsentwicklung von Kaninchen präzise beschreibt. Dabei hängt die Zahl der Kaninchen einer Generation n von der Summe der Zahl der Eltern-Generation (n-1) und der Zahl der Großeltern-Generation (n-2) ab. Fibonacci-Reihe: 1 1 2 3 5 8 13 21 34... rekursive Fassung: Anzahl der Aufrufe wächst exponentiell, daher ziemlich unbrauchbar! besser: iterative Fassung: int fib( int n) { if (n==0) return 0; if (n==1) return 1; return fib(n-1) + fib(n-2); } int fib( int n) { int i = 1; int x = 1, y = 0, z = 0; while (i<n) { z = x; x = x+y; y = z; i++; } return x; }
8
Institut für Wirtschaftsinformatik – Software Engineering, JKU Linz 8 Bäume - Definitionen Definition: nach Wirth [86, S. 200f] Eine Baumstruktur vom Grundtyp T ist entweder die leere Struktur oder ein Knoten vom Typ T mit einer endlichen Zahl verknüpfter, voneinander verschiedener Baumstrukturen vom Grundtyp T, sogennante Teilbäume (subtrees). Definition n. Sedgewick p. 230 ff Ein Baum ist ein Knoten (Wurzel), der mit einer Folge von disjunkten Bäumen verbunden ist. Eine derartige Folge nennt man Wald (forest). Ein Baum besteht aus Knoten (nodes), die durch Kanten (edges) verbunden sind. In den Knoten sind Nutzdaten (Elemente) gespeichert.
9
Institut für Wirtschaftsinformatik – Software Engineering, JKU Linz 9 Bäume - Begriffe Der Knoten an der Spitze heißt Wurzel des Baumes. Ein Pfad ist eine Liste von zusammenhängenden Kanten. Ausgehend von der Wurzel kann jeder Knoten über genau einen Pfad aus Kanten erreicht werden. Jeder Knoten, außer der Wurzel hat genau einen Vorgänger. Dieser wird auch als Elternknoten, Vater, Mutter (parent) bezeichnet. Die Nachfolgerknoten, die mit einem Vorgänger durch eine Kante verbunden sind bezeichnet man auch als Kindknoten, Sohn oder Tochter (children). Knoten ohne Nachfolger, werden als Bätter (leaves), Knoten mit Nachfolgern als innere Knoten bezeichnet. Die Ebene (Stufe, level) eines Knotens ist um 1 größer als die Ebene des Vorgängers (Wurzel hat Ebene = 0). Die Höhe eines Baumes ist das Maximum der Ebenen aller Knoten. Der Grad eines Baumes gibt die maximal mögliche Anzahl der direkten Nachfolgerknoten eines Knotens an. (Binärbaum: Grad = 2)
10
Institut für Wirtschaftsinformatik – Software Engineering, JKU Linz 10 Binärbaum und Binärer Suchbaum Binärbaum Ein Binärbaum ist ein Baum, dessen Grad 2 beträgt. l Ein Binärbaum mit N inneren Knoten hat N+1 Blätter. l Ein Binärbaum mit N inneren Knoten hat 2*N Kanten: N-1 zu inneren Knoten N+1 zu Blättern. Binärer Suchbaum (Definition n. Sedgewick p. 531) Ein binärer Suchbaum (binary search tree, BST) ist ein Binärbaum, der mit jedem inneren Knoten ein Schlüsselattribut assoziert und die Eigenschaft hat, dass für jeden Knoten K gilt: die Schlüsselwerte aller Knoten des linken Unterbaums sind kleiner (oder gleich) und die Schlüsselwerte des rechten Unterbaums sind größer (oder gleich) dem Schlüsselwert des Knotens K.
11
Institut für Wirtschaftsinformatik – Software Engineering, JKU Linz 11 Binärer Suchbaum in Jana type Tree = { reftype Item = { String key; int value} reftype Node = { Item item // Nutzdaten Node left, right} Node root // Wurzel init() {root = null}...//Algorithmen }//Tree //Verwendung: Tree t; t.init(); t.insert( item); Item i = t.search( key);
12
Institut für Wirtschaftsinformatik – Software Engineering, JKU Linz 12 void insert( Item x) { root=insertRec(root,x) } Item search( String key) { return searchRec(root,key) } Node insertRec( Node h, Item x) { if (h==null)return new Node(x) if (x.key < h.item.key) h.left = insertRec(h.left,x) else h.right = insertRec(h.right,x) return h; } Item searchRec( Node h, String key) { if (h==null) return null if (key==h.item.key) return h.item if (key < h.item.key) return searchRec(h.left,key) else return searchRec(h.right,key) } Binärer Suchbaum: Einfügen und Suchen (rekursiv)
13
Institut für Wirtschaftsinformatik – Software Engineering, JKU Linz 13 Binärer Suchbaum: Einfügen (iterativ) void insertIter(Item x) { if (root == null) { root = new Node(x) } else { Node parent, current = root while (true) { parent = current if (x.key < current.item.key) {// go left current = current.left if (current == null) { parent.left = new Node(x) return; } } else { // go right current = current.right if (current == null) { parent.right = new Node(x) return; } } // while } // else }
14
Institut für Wirtschaftsinformatik – Software Engineering, JKU Linz 14 Binärer Suchbaum: Suchen (iterativ) Item searchIter( String key) { Node current = root while (current != null) { if (current.item.key == key) return current.item if (key < current.item.key) { // go left current = current.left } else { // go right current = current.right } } // while return null //not found }
15
Institut für Wirtschaftsinformatik – Software Engineering, JKU Linz 15 Binärbaum: In-/Pre-/Postorder Traversierung (rekursiv) void inorder() { traverseInorderRec(root) } void traverseInorderRec( Node h) { if (h==null) return traverseInorderRec(h.left) h.item.visit() traverseInorderRec(h.right) } void traversePreorderRec( Node h) { if (h==null) return h.item.visit() traversePreOrderRec(h.left) traversePreOrderRec(h.right) } void traversePostorderRec( Node h) { if (h==null) return traversePostOrderRec(h.left) traversePostOrderRec(h.right) h.item.visit() }
16
Institut für Wirtschaftsinformatik – Software Engineering, JKU Linz 16 Binärbaum: Levelorder Traversierung (iterativ) void traverse() { traverseLevels(root) } void traverseLevels( Node h) { NodeQueue q = new NodeQueue q.enqueue(h) while (!q.isEmpty()) { h = q.dequeue() h.item.visit() if (h.left!=null) q.enqueue(h.left) if (h.right!=null) q.enqueue(h.right) }
Ähnliche Präsentationen
© 2024 SlidePlayer.org Inc.
All rights reserved.