KIT Jun.-Prof. Henning Meyerhenke, Jun.-Prof. Dennis Hofheinz Institut f¨ ur Theoretische Informatik Christian Staudt, Christoph Striecks ¨ 3. Ubungsblatt zu Algorithmen I im SS 2015 https://crypto.iti.kit.edu/algo-sose15 {staudt,striecks}@kit.edu Mit L¨ osungsvorschl¨ agen Aufgabe 1 (Rekursionsgleichungen, 4 + 4 Punkte) a) Zeigen Sie mittels vollst¨ andiger Induktion, dass f¨ ur ( 2 T (n) = 2T (dn/2e) + n2 falls n = 1, falls n ≥ 2, die Ungleichung T (n) ≤ 2n2 gilt. Dabei sei n eine Zweierpotenz. b) Zeigen Sie mittels Substitution, dass die L¨osung zu ( 9 falls n = 27, 1/3 T (n) = 9T ( n ) + log3 n falls n ≥ 28, i in Θ log2 n liegt. Dabei sei n = 33 , f¨ ur i ∈ N. L¨ osungsvorschlag: a) – Induktionsanfang: n = 1, T (1) = 2 ≤ 2 – Induktionsbehauptung: T (n) ≤ 2n2 – Induktionsschritt: n > 1, n nach 2n, T (2n) = 2T (n) + (2n)2 ≤ 4n2 + 4n2 = 8n2 = 2(2n)2 b) Wir setzen m = log3 n und erhalten T (33 ) = 9 und T (3m ) ≤ 9T (3m/3 ) + m, f¨ ur 3m ≥ 28. Wir setzen S(m) = T (3m ) und erhalten ( 9 falls m = 3, S(m) = 9S(m/3) + m falls m ≥ 4. Das Mastertheorem aus der Vorlesung liefert S(m) = Θ mlog3 9 = Θ m2 . Somit gilt S(m) = T (3m ) = T (n) = Θ log2 n . Aufgabe 2 (Einfach verkettete Listen, 8 Punkte) Gegeben sei folgende Implementierung der Datenstruktur einfach verkettete Liste: Eine Liste besteht aus Knoten (Objekte vom Typ Node), die jeweils ein Listenelement (data) und eine Referenz (next) auf den n¨achsten Knoten der Liste enthalten. Eine Liste wird als Referenz auf ihren ersten Knoten u ¨ bergeben. Der letzte Knoten der Liste enth¨alt eine leere Referenz (null). Seien L1 und L2 zwei einfach verkettete Listen, die Zahlen in aufsteigend sortierter Reihenfolge enthalten. Beide Listen sollen so miteinander verflochten werden, dass die resultierende einfach verkettete Liste M alle Knoten von L1 und L2 enth¨ alt und die Elemente in aufsteigender Reihenfolge sortiert sind. Schreiben Sie in Pseudocode eine Funktion, die L1 und L2 als Eingabe nimmt und M ausgibt. Ihre Funktion darf nur O(1) zus¨atzlichen Speicher benutzen und soll die Knoten der Eingabelisten wiederverwenden. An einem Knoten kann nur das Feld next ver¨ andert werden. 1 Lo ¨sungsvorschlag: Es folgt eine m¨ ogliche Implementierung der Datenstruktur und des Algorithmus in Python. (Die Angabe des Algorithmus in Pseudocode oder als klar verst¨andliche Implementierung in einer anderen realen Programmiersprache ist nat¨ urlich ebenfalls eine g¨ ultige L¨osung.) class Node: """ Simple singly-linked list node""" def __init__(self, data, next): """ Construct a list node from a data element and a reference to the following node""" self.data = data self.next = next class SortedListMerger: """ Sorted linked-list merging algorithm""" def __init__(self, h1, h2): """Construct with two heads of sorted lists as input""" self.h1 = h1 self.h2 = h2 self.head = None # head of result list self.tail = None # tail of result list def next(self): """ Returns next node in order, separated from origin list""" ret = None # border cases in which at least one input list is already empty if (self.h1 is None) and (self.h2 is None): return None if (self.h1 is None) and (self.h2 is not None): ret = self.h2 self.h2 = self.h2.next # advance h2 return ret if (self.h2 is None) and (self.h1 is not None): ret = self.h1 self.h1 = self.h1.next # advance h1 return ret # regular case if self.h1.data < self.h2.data: ret = self.h1 self.h1 = self.h1.next # advance h1 else: ret = self.h2 self.h2 = self.h2.next # advance h2 ret.next = None # cut node from input list return ret def merge(self): """ Merge lists given in constructor and return head of result list""" next = self.next() self.head = next self.tail = next while next is not None: next = self.next() self.tail.next = next self.tail = next return self.head Beispielaufruf h1 = Node(1, Node(4, Node(8, None))) h2 = Node(2, Node(4, Node(5, Node(17, Node(42, None))))) merger = SortedListMerger(h1, h2) h3 = merger.merge() print(h3) Aufgabe 3 (Amortisierte Analyse, 5 + 2 Punkte) Gegeben sei eine Datenstruktur, auf der eine Sequenz hσ1 , . . . , σn i von Operationen ausgef¨ uhrt wird. Die Operation σi , f¨ ur 1 ≤ i ≤ n, ben¨ otigt i3 Anweisungen, wenn i eine Dreierpotenz ist; anderenfalls ben¨otigt eine Operation 1 Anweisung. 2 a) Geben Sie eine geschlossene Form T (n) f¨ ur die Kosten von n Operationen an. Dabei sei n = 3m , f¨ ur m ∈ N. b) Geben Sie die amortisierten Kosten pro Operation an. L¨ osungsvorschlag: a) Wir zeigen T (n) ∈ O n3 . Sei cost(i) die Kosten-Funktion f¨ ur die i-te Operation. Wir setzen P3m m zun¨achst S(m) := T (3 ) = T (n) = i=1 cost(i) mit S(0) := 1. Weiterhin ist n = 3m . Nun stellt man S(m) als Rekurrenz dar, um nachher eine Summenformel zu bekommen. Das u ¨berlegt man sich folgendermaßen: Beim Inkrementieren von m − 1 auf m, f¨ ur m wie oben, haben alle Operationen zwischen 3m−1 und 3m die Kosten 1. Das sind genau 3m − 3m−1 − 1 viele. Die letzte Operation hat Kosten cost(3m ) = (3m )3 . Also ist S(m) = S(m − 1) + (3m )3 + (3m − 3m−1 − 1) = S(m − 1) + 33m + 2 · 3m−1 − 1. Ausrollen der Rekurrenz ergibt: S(m) = m X (27i + 2 · 3i−1 − 1) + S(0). i=1 Diese Summenformel vereinfacht man zu: S(m) = 1 − 27m+1 1 − 3m 27 3m 27 −1+2· −m+1= · 3 + 3m − m − . −26 −2 26 26 Und da m = log3 n gilt, erh¨ alt man durch R¨ uck-Substituieren eine Formel f¨ ur T (n): T (n) = 27 27 3 · n + n − log3 n − 26 26 (falls n eine Dreierpotenz ist). b) Als amortisierte Kosten pro Operation ergibt sich T (n) 27 2 log3 n 27 = ·n +1− − . n 26 n 26n Damit gilt T (n)/n ∈ O n2 , f¨ ur T (n) aus a). 3
© Copyright 2024