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();
}
}
}