Lausnum skal skilað til viðkomandi dæmakennara (sjá lista yfir dæmatíma).
Reynið að skrifa stutt, skýr og hnitmiðuð forrit. Notið réttan inndrátt og gætið þess að forritin ykkar séu læsileg.
Skiladagur: þriðjudaginn 20. mars fyrir kl 16:00
Leysið dæmi 3.2.1 í bókinni.
Draw the BST that results when you insert the keys E A S Y Q U E S T I O N, in that order (associating the value i with the ith key, as per the convention in the text) into an initially empty tree. How many compares are needed to build the tree?
Leysið dæmi 3.2.6 í bókinni.
Add to BST a method height() that computes the height of the tree. Develop two implementations: a recursive method (which takes linear time and space proportional to the height), and a method like size() that adds a field to each node in the tree (and takes linear space and constant time per query).
Beinagrind fyrir tvíleitartré: BST.java. Athugið að endurkvæm height() aðferð fylgir með beinagrindinni. Þið ættuð samt að reyna að skrifa ykkar eigin útgáfu frá grunni og skilja nákvæmlega hvernig hún virkar.
public int height() { return height(root); } private int height(Node x) { if (x == null) return -1; return 1 + Math.max(height(x.left), height(x.right)); }
private class Node { private Key key; // sorted by key private Value val; // associated data private Node left, right; // left and right subtrees private int N; // number of nodes in subtree private int height; // height of subtree public Node(Key key, Value val, int N) { this.key = key; this.val = val; this.N = N; this.height = 0; } } public int height() { return height(root); } private int height(Node x) { if (x == null) return 0; return x.height; } public void put(Key key, Value val) { if (val == null) { delete(key); return; } root = put(root, key, val); assert check(); } private Node put(Node x, Key key, Value val) { if (x == null) return new Node(key, val, 1); int cmp = key.compareTo(x.key); if (cmp < 0) x.left = put(x.left, key, val); else if (cmp > 0) x.right = put(x.right, key, val); else x.val = val; x.N = 1 + size(x.left) + size(x.right); x.height = 1 + Math.max(height(x.left), height(x.right)); return x; } public void deleteMin() { if (isEmpty()) throw new RuntimeException("Symbol table underflow"); root = deleteMin(root); assert check(); } private Node deleteMin(Node x) { if (x.left == null) return x.right; x.left = deleteMin(x.left); x.N = size(x.left) + size(x.right) + 1; x.height = 1 + Math.max(height(x.left), height(x.right)); return x; } public void deleteMax() { if (isEmpty()) throw new RuntimeException("Symbol table underflow"); root = deleteMax(root); assert check(); } private Node deleteMax(Node x) { if (x.right == null) return x.left; x.right = deleteMax(x.right); x.N = size(x.left) + size(x.right) + 1; x.height = 1 + Math.max(height(x.left), height(x.right)); return x; } public void delete(Key key) { root = delete(root, key); assert check(); } private Node delete(Node x, Key key) { if (x == null) return null; int cmp = key.compareTo(x.key); if (cmp < 0) x.left = delete(x.left, key); else if (cmp > 0) x.right = delete(x.right, key); else { if (x.right == null) return x.left; if (x.left == null) return x.right; Node t = x; x = min(t.right); x.right = deleteMin(t.right); x.left = t.left; } x.N = size(x.left) + size(x.right) + 1; x.height = 1 + Math.max(height(x.left), height(x.right)); return x; }
Leysið dæmi 2.4.5 í bókinni.
Give the heap that results when the keys E A S Y Q U E S T I O N are inserted in that order into an initially empty max-oriented heap.
Leysið dæmi 2.4.24 í bókinni.
Priority queue with explicit links. Implement a priority queue using a heap-ordered binary tree, but use a triply linked structure instead of an array. You will need three links per node: two to traverse down the tree and one to traverse up the tree. Your implementation should guarantee logarithmic running time per operation, even if no maximum priority-queue size is known ahead of time.
Skrifið notkunarlýsingu fyrir öll föll sem þið skrifið. Skrifið fastayrðingu gagna fyrir útfærslu ykkar á forgangsbiðröðinni. Skrifið fastayrðingu lykkju fyrir allar lykkjur sem þið skrifið.
Það er líka hægt að útfæra þetta án þess að geyma tilvísun á foreldri í hverjum hnút og ef þið gerið það þannig þá megið þið sleppa parent tilviksbreytunni og halda bara utan um tilvísun á vinstra og hægra undirtré.
Vísbending: þið getið geymt fjölda gilda í hverjum hnút (eins og size í BST) og notað það í innsetningu til að setja gildi á réttan stað í trénu þ.a. það fylli hverja hæð áður en það byrjar á næstu hæð.
public class PriQueue { // Gildin í forgangsbiðröðinni eru í hrúgu // með stærsta stak efst, root vísar á rótina // fyrir hrúguna. // Allar hæðir eru fullskipaðar nema e.t.v. sú // neðsta. private Node root; private static class Node { private String val; private Node left, right; private Node parent; int height; public Node(String val) { this.val = val; this.height = 0; } } // Notkun: pq = new PriQueue(); // Fyrir: Ekkert // Eftir: pq er ný tóm forgangsbiðröð public PriQueue() { root = null; } private static void fixUp(Node x) { while (x != null) { x.height = 1 + Math.max(height(x.left), height(x.right)); x = x.parent; } } // Notkun: x = pq.findBottomLeaf(root); // Fyrir: Ekkert // Eftir: x er lauf á neðstu hæðinni í trénu root private static Node findBottomLeaf(Node root) { Node x = root; while (!isLeaf(x)) { if (height(x.left) > height(x.right)) x = x.left; else x = x.right; } return x; } private static boolean isLeaf(Node x) { return x.left == null && x.right == null; } // Notkun: root = pq.removeLeaf(x); // Fyrir: x er lauf // Eftir: root er rót nýja hrúgu trésins sem kemur // út þegar hnútnum x er eytt úr trénu private static Node removeLeaf(Node x) { if (x.parent == null) return null; if (x.parent.left == x) x.parent.left = null; else x.parent.right = null; while (x.parent != null) { x.height = 1 + Math.max(height(x.left), height(x.right)); x = x.parent; } return x; } private static void rolldown(Node root) { Node x = root; while (!isLeaf(x)) { // root er hrúga nema e.t.v. er // gildið í x of ofarlega Node b = x.left; if (x.left == null) b = x.right; else if (x.right != null && x.left.val.compareTo(x.right.val) < 0) b = x.right; if (x.val.compareTo(b.val) > 0) break; swap(x, b); x = b; } } // Notkun: s = pq.deleteMax(); // Fyrir: pq er ekki tóm. // Eftir: s er eitt stærsta gildið sem var // í pq. s hefur verið fjarlægt úr pq. public String deleteMax() { String result = root.val; Node last = findBottomLeaf(root); root = removeLeaf(last); if (root != null) { root.val = last.val; rolldown(root); } return result; } private static void swap(Node a, Node b) { String tmp = a.val; a.val = b.val; b.val = tmp; } // Notkun: pq.put(s); // Fyrir: pq er ekki full. // Eftir: s hefur verið bætt við pq. public void put(String s) { root = put(root, s); } private static Node put(Node x, String s) { if (x == null) return new Node(s); if (s.compareTo(x.val) > 0) { String tmp = x.val; x.val = s; s = tmp; } int ls = height(x.left); int rs = height(x.right); if (ls <= rs) { x.left = put(x.left, s); x.left.parent = x; } else { x.right = put(x.right, s); x.right.parent = x; } x.height = 1 + Math.max(height(x.left), height(x.right)); return x; } public static int height(Node x) { if (x == null) return -1; return x.height; } public static void prettyPrint(int level, Node root) { if (level > 0) { for (int i = 0; i < level*2; i++) System.out.print(" "); } if (root == null) { System.out.print("()\n"); return; } if (root.left != null || root.right != null) { System.out.printf("(%s[%d]\n", root.val, root.height); prettyPrint(level+1, root.left); prettyPrint(level+1, root.right); for (int i = 0; i < level*2; i++) System.out.print(" "); System.out.println(")"); } else { System.out.printf("%s[%d]\n", root.val, root.height); } } public void prettyPrint() { prettyPrint(0, root); System.out.println(); } public boolean isEmpty() { return root == null; } public static void main(String[] args) { PriQueue pq = new PriQueue(); pq.put("F"); pq.put("B"); pq.put("D"); pq.put("C"); pq.put("A"); pq.put("H"); pq.put("P"); pq.put("C"); pq.put("Q"); pq.put("T"); pq.prettyPrint(); System.out.println("------------"); while (!pq.isEmpty()) { System.out.println(pq.deleteMax()); pq.prettyPrint(); } } }