===== Lösungsversuch =====
==== Aufgabe 1 Wissensfragen ====
**a)** 1 und 2
**b)** 2 und 3
**c)** 4
**d)** 2 und 4
**e)** 1
**f)** 1 und 3
**g)** 3 und 4
**h)** 1 und 4
**i)** 1 und 2
**j)** 1 und 3
* zu 4)
*=> Eine endrekursive Methode kann unmittelbar entrekursiviert werden.
* zu c)
*=> Laufzeit ist O(log(n))
==== Aufgabe 2 Suchen und O-Kalkül ====
**a)**
static int[] searchNaive(int[] a, int z) {
int[] r = null;
for(int i = 0; i < a.length; i++) {
for(int j = i+1; j < a.length; j++) {
if(a[i] + a[j] == z) {
r = new int[] {i, j};
}
}
}
return r;
}
**b)**
static int[] searchLinear(int[] a, int z) {
int i = 1, j = a.length - 1;
while(i < j) {
if(a[i] + a[j] == z) {
return new int[] {i, j};
} else if(a[i] + a[j] < z) {
i++;
} else {
j--;
}
}
}
**c)**
static LinkedList searchDuplicates(int[] a, int[] b) {
LinkedList ds = new LinkedList<>();
AVLTree at = new AVLTree();
for(int x : a) {
at.insert(x);
}
for(int x : b) {
AVLNode r = at.root;
while(r != null) {
if(x < r.data) {
r = r.left;
} else if(x > r.data) {
r = r.right;
} else {
ds.add(x);
break;
}
}
}
return ds;
}
====Aufgabe 3 Bäume ====
**a)**
| ^ B1 ^ B2 ^ B3 ^
^ Preorder: | ∧∨ab∨cd | ∨∧ab¬∨cd | ∨¬a∧¬b∨¬cd |
^ Inorder: | (a∨b)∧(c∨d)) | a∧b∨¬(c∨d) | ¬a∨¬b∧(¬c∨d) |
^ Postorder: | ab∨cd∨∧ | ab∧cd∨¬∨ | a¬b¬c¬d∨∧∨ |
**b)**
LinkedList toPrefix() {
LinkedList r = new LinkedList<>();
r.add(o);
for(KTree c : cs) {
r.addAll(c.toPrefix());
}
return r;
}
static KTree fromPostfix(LinkedList postfix) {
Stack s = new Stack<>();
for(KOp o : postfix) {
switch(o) {
case AND:
case OR:
KTree r = s.pop();
KTree l = s.pop();
s.push(new KTree(o, l, r));
break;
case NOT:
s.push(new KTree(o, s.pop()));
break;
default:
s.push(new KTree(o));
}
}
return s.pop();
}
====Aufgabe 4 Listen ===
**a)**
public boolean contains(E e) {
Node cur = head;
for(int l = LEVELS - 1; l >= 0; l--) {
while(cur.next[l] != null && cur.next[l].e.compareTo(e) <= 0) {
if(cur.next[l].e.compareTo(e) == 0) {
return true;
}
cur = cur.next[l];
}
}
return false;
}
**b)**
private Node[] getPred(E e) {
Node[] last = (Node []) Array.newInstance(Node.class, LEVELS);
Node cur = head;
for(int l = LEVELS - 1; l >= 0; l--) {
while(cur.next[l] != null && cur.next[l].e.compareTo(e) < 0) {
cur = cur.next[l];
}
last[l] = cur;
}
return last;
}
**c)**
public boolean insert(E e) {
Node newN = new Node(e);
int newL = getRandomLevel();
if(contains(e)) {
return false;
}
Node[] pred = getPred(e);
for(int l = newL; l >= 0; l--) {
newN.next[l] = pred[l].next[l];
pred[l].next[l] = newN;
}
return true;
}
public boolean delete(E e) {
if(!contains(e)) {
return false;
}
Node[] pred = getPred(e);
for(int l = LEVELS - 1; l >= 0; l--) {
if(pred[l].next[l] != null) {
pred[l].next[l] = pred[l].next[l].next[l];
}
}
return true;
}
====Aufgabe 5 ADT====
**a)**
as2gh(Create, Create, k) = Node(New, k)
as2gh(Add(n, ns), as, k) = Edge(as2gh(ns, as, k), k, n)
as2gh(Create, Add(ns, as), k) = Node(as2gh(ns, as, k+1), k)
**b)**
flatten(Add(Create, as)) = flatten(as)
flatten(Add(Add(n, ns), as)) = Add(n, flatten(Add(ns, as)))
**c)**
as2af(as) = as2afh(length(as)+1, as, flatten(as))
as2afh(si, Create, af)) = Add(si, af)
as2afh(si, Add(ns, as), af) = Add(si, as2afh(si+length(ns), as, af))
====Aufgabe 6 Graphen====
**a)**
boolean isSafe(boolean g[][], int cs[], int v, int c) {
for (int n = 0; n < g.length; n++) {
if (g[v][n] == true && c == cs[n]) {
// Kante vorhanden und Farbe bereits vergeben
return false;
}
}
return true;
}
**b)**
boolean helper(boolean g[][], int cs[], int m, int v) {
// base case
if (v >= g.length) {
return true;
}
// try different colors for vertex v
for (int c = 1; c <= m; c++) {
if (isSafe(g, cs, v, c)) {
int color = cs[v]; // aktuelle Farbe sichern
cs[v] = c; // neue Farbe setzen
if (helper(g, cs, c, v + 1)) { // Rekursion (Fehler?: sollte m statt c sein)
return true;
}
// backtrack
cs[v] = color;
}
}
// keine Loesung gefunden -> Schritt zurueck
return false;
}
**c)**
int[] color(boolean g[][], int m) {
int[] cs = new int[g.length];
if (!helper(g, cs, m, 0)) {
return null;
}
return cs;
}