Difference between revisions of "CSC212 Homework 6 Solutions 2014"
(Created page with "--~~~~ ---- =Problem 1= <br /> <source lang="java"> </source> <br /> =Problem 2= <br /> <source lang="java"> </source> <br /> =Problem 3= <br /> <source lang="java"> </so...") |
|||
Line 1: | Line 1: | ||
--[[User:Thiebaut|D. Thiebaut]] ([[User talk:Thiebaut|talk]]) 12:13, 31 October 2014 (EDT) | --[[User:Thiebaut|D. Thiebaut]] ([[User talk:Thiebaut|talk]]) 12:13, 31 October 2014 (EDT) | ||
---- | ---- | ||
+ | <onlydft> | ||
=Problem 1= | =Problem 1= | ||
<br /> | <br /> | ||
<source lang="java"> | <source lang="java"> | ||
+ | private void generateDotLowKey( IntBSTNode p ) { | ||
+ | if ( p==null ) | ||
+ | return; | ||
+ | if ( p.left != null ) | ||
+ | System.out.println( p.key + " -> " + p.left.key +";" ); | ||
+ | if ( p.right != null ) | ||
+ | System.out.println( p.key + " -> " + p.right.key +";" ); | ||
+ | |||
+ | generateDot( p.left ); | ||
+ | generateDot( p.right ); | ||
+ | } | ||
+ | |||
</source> | </source> | ||
Line 11: | Line 24: | ||
<br /> | <br /> | ||
<source lang="java"> | <source lang="java"> | ||
+ | |||
+ | private void generateDot( IntBSTNode p ) { | ||
+ | if ( p==null ) | ||
+ | return; | ||
+ | if ( p.left != null ) | ||
+ | System.out.println( p.key + " -> " + p.left.key +";" ); | ||
+ | else { | ||
+ | String nullNode = "null" + p.key + "left [label=\"\",width=.1,style=invis]"; | ||
+ | System.out.println( nullNode + ";" ); | ||
+ | System.out.println( p.key + " -> " + nullNode + " [style=invis];" ); | ||
+ | } | ||
+ | if ( p.right != null ) | ||
+ | System.out.println( p.key + " -> " + p.right.key +";" ); | ||
+ | else { | ||
+ | String nullNode = "null" + p.key + "right [label=\"\",width=.1,style=invis]"; | ||
+ | System.out.println( nullNode + ";" ); | ||
+ | System.out.println( p.key + " -> " + nullNode + " [style=invis];" ); | ||
+ | } | ||
+ | |||
+ | generateDot( p.left ); | ||
+ | generateDot( p.right ); | ||
+ | } | ||
</source> | </source> | ||
Line 18: | Line 53: | ||
<br /> | <br /> | ||
<source lang="java"> | <source lang="java"> | ||
+ | /** | ||
+ | * StringBST.java | ||
+ | * @author D. Thiebaut | ||
+ | * All material taken, and adapted from Drozdek's | ||
+ | * Data Structures and Algorithms in Java. | ||
+ | * | ||
+ | */ | ||
+ | import java.util.ArrayList; | ||
+ | import java.util.Collections; | ||
+ | import java.util.LinkedList; | ||
+ | import java.util.Queue; | ||
+ | |||
+ | /** | ||
+ | * A class implementing a BST node, with an integer key, and a left and right | ||
+ | * pointer. | ||
+ | * | ||
+ | * @author thiebaut | ||
+ | * | ||
+ | */ | ||
+ | class StringBSTNode { | ||
+ | |||
+ | public String key; | ||
+ | public int counter; | ||
+ | public StringBSTNode left, right; | ||
+ | |||
+ | StringBSTNode(String el, StringBSTNode l, StringBSTNode r) { | ||
+ | key = el; | ||
+ | left = l; | ||
+ | right = r; | ||
+ | counter = 1; | ||
+ | } | ||
+ | |||
+ | StringBSTNode(String el) { | ||
+ | this(el, null, null); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * The tree class. Implements most useful methods. | ||
+ | * | ||
+ | * @author thiebaut | ||
+ | * | ||
+ | */ | ||
+ | public class StringBST { | ||
+ | protected StringBSTNode root; | ||
+ | protected int nodeCounter; | ||
+ | private ArrayList<String> mostFrequentStrings; | ||
+ | private int mostFrequentCounter; | ||
+ | |||
+ | /** | ||
+ | * constructor creates an empty tree. | ||
+ | */ | ||
+ | StringBST() { | ||
+ | root = null; | ||
+ | } | ||
+ | |||
+ | protected void setRoot(StringBSTNode p) { | ||
+ | root = p; | ||
+ | } | ||
+ | |||
+ | public void clear() { | ||
+ | root = null; | ||
+ | } | ||
+ | |||
+ | public int length() { | ||
+ | nodeCounter = 0; | ||
+ | visitCountNodes(root); | ||
+ | return nodeCounter; | ||
+ | } | ||
+ | |||
+ | private void visitCountNodes(StringBSTNode p) { | ||
+ | if (p == null) | ||
+ | return; | ||
+ | nodeCounter++; | ||
+ | visitCountNodes(p.left); | ||
+ | visitCountNodes(p.right); | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * Just use for debugging... Recursively visits the tree and display | ||
+ | * information about what it finds. | ||
+ | */ | ||
+ | protected void debugVisit() { | ||
+ | debugVisit(root); | ||
+ | } | ||
+ | |||
+ | protected void debugVisit(StringBSTNode p) { | ||
+ | if (p == null) | ||
+ | return; | ||
+ | String leftString = "has no left child", rightString = "has no right child"; | ||
+ | if (p.left != null) | ||
+ | leftString = "has " + p.left.key + " as left child"; | ||
+ | if (p.right != null) | ||
+ | rightString = "has " + p.right.key + " as right child"; | ||
+ | System.out.println("Node " + p.key + ", " + leftString + ", and " | ||
+ | + rightString); | ||
+ | debugVisit(p.left); | ||
+ | debugVisit(p.right); | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * Iteratively searches for an element in the tree. Returns the node | ||
+ | * containing the element if found, or null otherwise. | ||
+ | * | ||
+ | * @param el | ||
+ | * @return | ||
+ | */ | ||
+ | public StringBSTNode search(String el) { | ||
+ | StringBSTNode p = root; | ||
+ | while (p != null) { | ||
+ | if (el.equals(p.key)) | ||
+ | return p; | ||
+ | if (el.compareTo(p.key) < 0) | ||
+ | p = p.left; | ||
+ | else | ||
+ | p = p.right; | ||
+ | } | ||
+ | return null; | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * recursively searches for an element in the tree. Returns the node | ||
+ | * containing the element, or null if not found. | ||
+ | * | ||
+ | * @param el | ||
+ | * @return | ||
+ | */ | ||
+ | public StringBSTNode recSearch(String el) { | ||
+ | return recSearch(root, el); | ||
+ | } | ||
+ | |||
+ | private StringBSTNode recSearch(StringBSTNode p, String el) { | ||
+ | if (p == null) | ||
+ | return null; | ||
+ | if (el.equals(p.key)) | ||
+ | return p; | ||
+ | if (el.compareTo(p.key) < 0) | ||
+ | return recSearch(p.left, el); | ||
+ | else | ||
+ | return recSearch(p.right, el); | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * Find most frequent words in tree. | ||
+ | * findMostFrequent() is the main entry point for this set of 3 functions | ||
+ | * findMostFrequent( StringBSTNode ) is the one that explores recursively and | ||
+ | * computes the max frequency found in the nodes | ||
+ | * findMostFrequent( StringBSTNode, int ) is the one we call after the previous | ||
+ | * one, once we know the max frequency, and this function locates all the nodes | ||
+ | * that have counters equal to the max frequency, and insert the keys in the | ||
+ | * member variable (field) that is an arrayList of strings. | ||
+ | * | ||
+ | public ArrayList<String> findMostFrequent() { | ||
+ | mostFrequentCounter = 0; | ||
+ | findMostFrequent( root ); | ||
+ | //System.out.println( "mostFrequentCounter = " + mostFrequentCounter ); | ||
+ | mostFrequentStrings = new ArrayList<String>(); | ||
+ | findMostFrequent( root, mostFrequentCounter ); | ||
+ | return mostFrequentStrings; | ||
+ | } | ||
+ | |||
+ | public void findMostFrequent( StringBSTNode p ) { | ||
+ | if ( p==null ) | ||
+ | return; | ||
+ | if ( p.counter > mostFrequentCounter ) | ||
+ | mostFrequentCounter = p.counter; | ||
+ | findMostFrequent( p.left ); | ||
+ | findMostFrequent( p.right ); | ||
+ | } | ||
+ | |||
+ | public void findMostFrequent( StringBSTNode p, int maxFreq ) { | ||
+ | if ( p==null ) | ||
+ | return; | ||
+ | if ( p.counter == maxFreq ) | ||
+ | mostFrequentStrings.add( p.key ); | ||
+ | findMostFrequent( p.left, maxFreq ); | ||
+ | findMostFrequent( p.right, maxFreq ); | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * visits the tree in order and list the keys along with their frequencies. | ||
+ | */ | ||
+ | public void inOrderVisitDuplicates() { | ||
+ | inOrderVisitDuplicates(root); | ||
+ | System.out.println(); | ||
+ | } | ||
+ | |||
+ | private void inOrderVisitDuplicates(StringBSTNode p) { | ||
+ | if (p == null) | ||
+ | return; | ||
+ | inOrderVisitDuplicates(p.left); | ||
+ | System.out.println(p.key + " (" + p.counter + ") " ); | ||
+ | inOrderVisitDuplicates(p.right); | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * Traveral methods inOrderVisit preOrderVisit postOrderVisit | ||
+ | */ | ||
+ | public void inOrderVisit() { | ||
+ | inOrderVisit(root); | ||
+ | System.out.println(); | ||
+ | } | ||
+ | |||
+ | private void inOrderVisit(StringBSTNode p) { | ||
+ | if (p == null) | ||
+ | return; | ||
+ | inOrderVisit(p.left); | ||
+ | System.out.print(p.key + " "); | ||
+ | inOrderVisit(p.right); | ||
+ | } | ||
+ | |||
+ | public void preOrderVisit() { | ||
+ | preOrderVisit(root); | ||
+ | System.out.println(); | ||
+ | } | ||
+ | |||
+ | private void preOrderVisit(StringBSTNode p) { | ||
+ | if (p == null) | ||
+ | return; | ||
+ | System.out.print(p.key + " "); | ||
+ | preOrderVisit(p.left); | ||
+ | preOrderVisit(p.right); | ||
+ | } | ||
+ | |||
+ | public void postOrderVisit() { | ||
+ | postOrderVisit(root); | ||
+ | System.out.println(); | ||
+ | } | ||
+ | |||
+ | private void postOrderVisit(StringBSTNode p) { | ||
+ | if (p == null) | ||
+ | return; | ||
+ | postOrderVisit(p.left); | ||
+ | postOrderVisit(p.right); | ||
+ | System.out.print(p.key + " "); | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * visits the tree breadth-first. Display the key in all the nodes, in | ||
+ | * breadth-first order. | ||
+ | */ | ||
+ | public void breadthFirst() { | ||
+ | StringBSTNode p = root; | ||
+ | Queue<StringBSTNode> queue = new LinkedList<StringBSTNode>(); | ||
+ | |||
+ | if (p == null) | ||
+ | return; | ||
+ | |||
+ | queue.add(p); | ||
+ | while (!queue.isEmpty()) { | ||
+ | p = queue.poll(); | ||
+ | // --- do some work with the key. Here we just print it... | ||
+ | System.out.print(p.key + " "); | ||
+ | if (p.left != null) | ||
+ | queue.add(p.left); | ||
+ | if (p.right != null) | ||
+ | queue.add(p.right); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * Inserts an element in the tree. We assume that the element is not already | ||
+ | * there. | ||
+ | * | ||
+ | * @param el | ||
+ | */ | ||
+ | public void insert(String el) { | ||
+ | // is the tree empty? if so, create 1 node | ||
+ | if (root == null) { | ||
+ | root = new StringBSTNode(el); | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | // go down to the leaf that will be the parent | ||
+ | // of the new node | ||
+ | StringBSTNode p = root, prev = null; | ||
+ | while (p != null) { | ||
+ | prev = p; | ||
+ | if (p.key.compareTo(el) < 0) | ||
+ | p = p.right; | ||
+ | else | ||
+ | p = p.left; | ||
+ | } | ||
+ | |||
+ | // add element as new leaf of prev's node | ||
+ | if (el.compareTo(prev.key) < 0) | ||
+ | prev.left = new StringBSTNode(el); | ||
+ | else | ||
+ | prev.right = new StringBSTNode(el); | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * inserts an element in the tree, and if it is already there, then increment | ||
+ | * a counter for that already existing node. OTherwise create a new node and | ||
+ | * set its counter to 1. | ||
+ | * @param el | ||
+ | */ | ||
+ | public void insertWithDuplicates(String el) { | ||
+ | // is the tree empty? if so, create 1 node | ||
+ | if (root == null) { | ||
+ | root = new StringBSTNode(el); | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | // go down to the leaf that will be the parent | ||
+ | // of the new node | ||
+ | StringBSTNode p = root, prev = null; | ||
+ | while (p != null) { | ||
+ | prev = p; | ||
+ | if (p.key.equals(el)) { | ||
+ | p.counter++; | ||
+ | return; | ||
+ | } | ||
+ | if (p.key.compareTo(el) < 0) | ||
+ | p = p.right; | ||
+ | else | ||
+ | p = p.left; | ||
+ | } | ||
+ | |||
+ | // add element as new leaf of prev's node | ||
+ | if (el.compareTo(prev.key) < 0) | ||
+ | prev.left = new StringBSTNode(el); | ||
+ | else | ||
+ | prev.right = new StringBSTNode(el); | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * Delete element by merging. Finds the element, then the largest of its | ||
+ | * left-subtree, and attaches the right-subtree of the node to delete to | ||
+ | * this largest element. | ||
+ | * | ||
+ | * @param el | ||
+ | * : the key we want to remove. | ||
+ | */ | ||
+ | public void delete(String el) { | ||
+ | StringBSTNode tmp, node, p = root, prev = null; | ||
+ | |||
+ | if (root == null) { | ||
+ | System.out.println("Trying to delete from an empty tree"); | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | // find the node containing el | ||
+ | while (p != null && p.key.equals(el) == false) { | ||
+ | prev = p; | ||
+ | if (p.key.compareTo(el) < 0) | ||
+ | p = p.right; | ||
+ | else | ||
+ | p = p.left; | ||
+ | } | ||
+ | |||
+ | if (p == null) { | ||
+ | System.out.println("Key " + el + " not in tree"); | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | // we found the element. p is pointing to it. prev is pointing to | ||
+ | // parent (or is null if el is in root). | ||
+ | node = p; | ||
+ | |||
+ | // no right sub-tree? | ||
+ | if (node.right == null) { | ||
+ | // yes, then pick the left subtree | ||
+ | node = node.left; | ||
+ | } else if (node.left == null) { | ||
+ | // yes, then pick the right subtree | ||
+ | node = node.right; | ||
+ | } else { | ||
+ | // two existing subtrees. | ||
+ | // go to left subtree | ||
+ | tmp = node.left; | ||
+ | |||
+ | // and find the right-most node that doesn't have a right child. | ||
+ | while (tmp.right != null) | ||
+ | tmp = tmp.right; | ||
+ | |||
+ | // tmp points to right-most node (blue node) | ||
+ | |||
+ | // attach right subtree of node we're deleting (yellow node) | ||
+ | // to right most node (blue node) | ||
+ | tmp.right = node.right; | ||
+ | |||
+ | node = node.left; | ||
+ | } | ||
+ | |||
+ | if (p == root) | ||
+ | root = node; | ||
+ | else if (prev.left == p) | ||
+ | prev.left = node; | ||
+ | else | ||
+ | prev.right = node; | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * balance the tree by copying all the keys into an array first, then | ||
+ | * sorting the array, then doing some binary split operation, going to the | ||
+ | * middle of the array to find the root, then to the middle of the two | ||
+ | * halves to find the children of the root, etc... and rebuilding the tree | ||
+ | * that way. | ||
+ | * | ||
+ | * @return | ||
+ | */ | ||
+ | private void addNodeToArray(StringBSTNode p, ArrayList<String> allNodes) { | ||
+ | if (p == null) | ||
+ | return; | ||
+ | addNodeToArray(p.left, allNodes); | ||
+ | allNodes.add(p.key); | ||
+ | addNodeToArray(p.right, allNodes); | ||
+ | } | ||
+ | |||
+ | public void balance() { | ||
+ | // visit the tree and copy all the nodes into an ArrayList | ||
+ | // visit in in-order fashion, so as to create a sorted list of keys in | ||
+ | // the array | ||
+ | ArrayList<String> allNodes = new ArrayList<String>(); | ||
+ | addNodeToArray(root, allNodes); | ||
+ | |||
+ | // recursively reconstruct the tree | ||
+ | clear(); | ||
+ | recursiveBalance(allNodes, 0, allNodes.size() - 1); | ||
+ | } | ||
+ | |||
+ | private void recursiveBalance(ArrayList<String> allNodes, int low, int high) { | ||
+ | if (low <= high) { | ||
+ | int mid = (low + high) / 2; | ||
+ | insert(allNodes.get(mid)); | ||
+ | recursiveBalance(allNodes, low, mid - 1); | ||
+ | recursiveBalance(allNodes, mid + 1, high); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * generateDot: generates the dot representation of the tree. | ||
+ | */ | ||
+ | public void generateDot() { | ||
+ | System.out.println("digraph T {\nlabel = \"Mickey Mouse\";"); | ||
+ | generateDot(root); | ||
+ | System.out.println("}"); | ||
+ | } | ||
+ | |||
+ | private void generateDotLowKey(StringBSTNode p) { | ||
+ | if (p == null) | ||
+ | return; | ||
+ | if (p.left != null) | ||
+ | System.out.println(p.key + " -> " + p.left.key + ";"); | ||
+ | if (p.right != null) | ||
+ | System.out.println(p.key + " -> " + p.right.key + ";"); | ||
+ | |||
+ | generateDot(p.left); | ||
+ | generateDot(p.right); | ||
+ | } | ||
+ | |||
+ | private void generateDot(StringBSTNode p) { | ||
+ | if (p == null) | ||
+ | return; | ||
+ | if (p.left != null) | ||
+ | System.out.println(p.key + " -> " + p.left.key + ";"); | ||
+ | else { | ||
+ | String nullNode = "null" + p.key | ||
+ | + "left [label=\"\",width=.1,style=invis]"; | ||
+ | System.out.println(nullNode + ";"); | ||
+ | System.out.println(p.key + " -> " + nullNode + " [style=invis];"); | ||
+ | } | ||
+ | if (p.right != null) | ||
+ | System.out.println(p.key + " -> " + p.right.key + ";"); | ||
+ | else { | ||
+ | String nullNode = "null" + p.key | ||
+ | + "right [label=\"\",width=.1,style=invis]"; | ||
+ | System.out.println(nullNode + ";"); | ||
+ | System.out.println(p.key + " -> " + nullNode + " [style=invis];"); | ||
+ | } | ||
+ | |||
+ | generateDot(p.left); | ||
+ | generateDot(p.right); | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * M A I N P R O G R A M | ||
+ | * | ||
+ | */ | ||
+ | static public void main(String[] args) { | ||
+ | |||
+ | } | ||
+ | } | ||
</source> | </source> | ||
<br /> | <br /> | ||
<br /> | <br /> | ||
+ | </onlydft> | ||
<br /> | <br /> | ||
<br /> | <br /> |