Syntatic Sugar - a bunch of static’s public static Tree leaf () { return new Tree(); } public static Tree node (Object val, Tree lt, Tree rt) { return new Tree(val, lt, rt); } public static boolean isLeaf (Tree t) { return t.isLeaf; } public static Object getValue(Tree t) { return t.getValue(); } public static Tree getLeft(Tree t) { return t.getLeft(); } public static Tree getRight(Tree t){ return t.getRight(); } public static void setValue (Tree t, Object newValue) { t.setValue(newValue); } public static void setLeft (Tree t, Tree newLeft) { t.setLeft(newLeft); } public static void setRight (Tree t, Tree newRight) { t.setRight(newRight); } // using the new notation: Tree T = leaf(); T = node("A", leaf(), leaf()); Tree tl = node("B", leaf(), leaf()); Tree tr = node("C", leaf(), leaf()); setLeft(T, tl); setRight(T, tr); setValue(getLeft(T),new Integer(5)); setRight(T, getRight(getRight(T)) ); 17 - 18

Schreiber, Schwöbbermeyer [12] proposed flexible pattern finder (FPF) in a system Mavisto.[23] It exploits downward closure , applicable for frequency concepts F2 and F3. The downward closure property asserts that the frequency for sub-graphs decrease monotonically by increasing the size of sub-graphs; but it does not hold necessarily for frequency concept F1. FPF is based on a pattern tree (see figure) consisting of nodes that represents different graphs (or patterns), where the parent is a sub-graph of its children nodes; i.e., corresp. graph of each pattern tree’s node is expanded by adding a new edge of its parent node. At first, FPF enumerates and maintains info of all matches of a sub-graph at the root of the pattern tree. Then builds child nodes of previous node by adding 1 edge supported by a matching edge in target graph, tries to expand all of previous info about matches to the new sub-graph (child node).[In next step, it decides whether the frequency of the current pattern is lower than a predefined threshold or not. If it is lower and if downward closure holds, FPF can abandon that path and not traverse further in this part of the tree; as a result, unnecessary computation is avoided. This procedure is continued until there is no remaining path to traverse. It does not consider infrequent sub-graphs and tries to finish the enumeration process as soon as possible; therefore, it only spends time for promising nodes in the pattern tree and discards all other nodes. As an added bonus, the pattern tree notion permits FPF to be implemented and executed in a parallel manner since it is possible to traverse each path of the pattern tree independently. But, FPF is most useful for frequency concepts F2 and F3, because downward closure is not applicable to F1. Still the pattern tree is still practical for F1 if the algorithm runs in parallel. It has no limitation on motif size, which makes it more amenable to improvements. ESU (FANMOD) Sampling bias of Kashtan et al. [9] provided great impetus for designing better algs for NM discovery, Even after weighting scheme, this method imposed an undesired overhead on the running time as well a more complicated impl. It supports visual options and is time efficient. But it doesn’t allow searching for motifs of size 9. Wernicke [10] RAND-ESU is better than jfinder, based on the exact enumeration algorithm ESU, has been implemented as an app called FANMOD.[10] Rand-esu is a discovery alg applicable for both directed and undirected networks. It effectively exploits an unbiased node sampling, and prevents overcounting sub-graphs. RAND-ESU uses DIRECT for determining sub-graph significance instead of an ensemble of random networks as a Null-model. DIRECT estimates sub-graph # w/oexplicitly generating random networks.[10] Empirically, DIRECT is more efficient than random network ensemble for sub-graphs with a very low concentration. But classical Null-model is faster than DIRECT for highly concentrated sub-graphs.[3][10] ESU alg: We show how this exact algorithm can be modified efficiently to RAND-ESU that estimates sub-graphs concentrations. The algorithms ESU and RAND-ESU are fairly simple, and hence easy to implement. ESU first finds the set of all induced sub-graphs of size k, let Sk be this set. ESU can be implemented as a recursive function; the running of this function can be displayed as a tree-like structure of depth k, called the ESU-Tree (see figure). Each of the ESU-Tree nodes indicate the status of the recursive function that entails two consecutive sets SUB and EXT. SUB refers to nodes in the target network that are adjacent and establish a partial sub-graph of size |SUB|≤k. If |SUB|=k, alg has found induced complete sub-graph, Sk=SUB ∪Sk. If |SUB|v} graphs of size 3 in the target graph. call ExtendSubgraph({v}, VExtension, v) endfor Leaves: set S3 or all of size-3 induced sub-graphs of the target graph (a). ESUtree nodes incl 2 adjoining sets: adjacent ExtendSubgraph(VSubgraph, VExtension, v) nodes called SUB and EXT=all adjacent if |VSubG|=k output G[VSubG] return 1 SUB node and where their numerical While VExt≠∅ do Remove arbitrary vertex w from VExt labels > SUB nodes labels. EXT set is VExtension′←VExtension∪{u∈Nexcl(w,VSubgraph)|u>v} utilized by the alg to expand a SUB set call ExtendSubgraph(VSubgraph ∪ {w}, VExtension′, v) until it reaches a desired size placed at return lowest level of ESU-Tree (or its leaves).

Sample JTree Methods • • • • • JTree related classes – JTree (Java tree class) – DefaultTreeModel (Object that controls how tree displays) – DefaultMutableTreeNode (nodes to hold data in the tree) Instantiate – A Node for the tree: root = new DefaultMutableTreeNode(“name”); – Tree Model: treeModel = new DefaultTreeModel(root); – A JTree: tree = Jtree(treeModel); Add a node to the root, make it display, and highlight the new node – root.add(new DefaultMutableTreeNode("child node"); – tree.scrollPathToVisible(new TreePath(child.getPath())); – treeModel.nodeStructureChanged(parent); – tree.setSelectionPath( (newTreePath(node.getPath()))); Display tree: for (int r=0; r=0;r--) tree.collapseRow(r); More information is in the lab instructions

Sample Driver For Array Implementation // Program file: TreeDriver.cpp ////////////////////////////////// // This program illustrates the // // creation of a binary tree. // ////////////////////////////////// #include #include "BinTree.h" using namespace std; void print_tree(binary_tree &tree); // The main function queries the // // user for new tree elements. // void main() { binary_tree tree; int number; cout << "Enter a number: "; cin >> number; while (number > 0) { tree.insert(number); tree.display_array(); cout << "Enter a number: "; cin >> number; } } CS 240 // The print_tree function outputs the final // // contents of the tree, first by displaying // // the entire array, then by printing out // // the non-vacant tree elements in inorder, // // preorder, and postorder. // void print_tree(binary_tree &tree) { cout << "Array contents:" << endl; tree.display_array(); cout << endl << "Inorder traversal: " << endl; tree.inorder_traverse(0); cout << endl; cout << "Preorder traversal: " << endl; tree.preorder_traverse(0); cout << endl; cout << "Postorder traversal: " << endl; tree.postorder_traverse(0); cout << endl << endl; } print_tree(tree); 14

Example public static void main(String[] args) { Tree T = new Tree(); T = new Tree("A", new Tree(), new Tree()); Tree tl = new Tree("B", new Tree(), new Tree()); Tree tr = new Tree("C", new Tree(), new Tree()); T.setLeft(tl); T.setRight(tr); T.getLeft().setValue(new Integer(5)); T.setRight(T.getRight().getRight() ); • Draw T’s contents . (. A .) ((. B .) A (. C .)) ((. 5 .) A (. C .)) ((. 5 .) A .) } 17 - 12

public class Tree implements TreeInterface { // instance variables private Object value; private Tree left, right; private boolean isLeaf; // constructors public Tree () { isLeaf = true; } public Tree (Object value, Tree lt, Tree rt) { this.value = value; this.left = lt; this.right = rt; isLeaf = false; } // instance methods public boolean isLeaf () { // returns true if the tree is a leaf (i.e. empty tree) return isLeaf; } public Object getValue () { if (isLeaf) throw new RuntimeException ("Attempt to get value of empty tree"); else return value; } public Tree getLeft () { if (isLeaf) throw new RuntimeException ("Attempt to get left subtree of an empty tree"); else return left; } public Tree getRight () { if (isLeaf) throw new RuntimeException ("Attempt to get right subtree of an empty tree"); else return right; } 17 - 14

Tree Contract (interface + instance vars) public Tree () public Tree (Object val, Tree lt, Tree rt) private private private private lt value isLeaf rt Tree lt; Object value; boolean isLeaf; Tree rt; public boolean isLeaf () public Object getValue () public void setValue (Object newValue) public Tree getLeft () public void setLeft (Tree newLeft) public Tree getRight () public void setRight (Tree newRight) “Jane” F public String toString () “Sally” / “” T / / “” T / / “” F “Joe” T / / “” F T 17 - 21/

Tree Implementation Contract public Tree () public Tree (Object val, Tree lt, Tree rt) private Object value; private Tree lt, rt; private boolean isLeaf; lt value isLeaf rt public boolean isLeaf () public Object getValue () public Tree getLeft () public Tree getRight () public void setValue (Object newValue) “Jane” F public void setLeft (Tree newLeft) public void setRight (Tree newRight) “Sally” F “Joe” F public String toString () / “” T / / “” T / / “” T / / “” T 17 - 13/

Delete a Node in BST Algorithm: if (Left(tree) is NULL) AND (Right(tree) is NULL) Set tree to NULL else if Left(tree) is NULL Set tree to Right(tree) else if Right(tree) is NULL Set tree to Left(tree) else Find predecessor Set Info(tree) to Info(predecessor) Delete predecessor Indirect Recursion!

B tree of order p 1. Each internal node in the B-tree is of the form , P2, , ..., , Pq> where q 1 p. Each Pi is a tree pointer—a pointer to another node in the B-tree. Each Pri is a data pointer —a pointer to the record whose search key field value is equal to Ki (or to the data file block containing that record). 2. Within each node, K1

Example Driver For The Heap Application // Program file: heapdriv.cpp // This program illustrates // the creation of a heap. #include #include "heap.h" // // // void print_heap(heap &tree); // The main function queries the // // user for new heap elements. // void main() { heap tree; int number; CS 240 } cout << "Enter a number: "; cin >> number; while (number > 0) { tree.insert(number); tree.display_array(); cout << "Enter a number: "; cin >> number; } print_heap(tree); // The print_heap function outputs // // the final contents of the heap, // // first by displaying the entire // // array, then by printing out the // // non-vacant heap elements in in- // // order, preorder, and postorder. // void print_heap(heap &tree) { cout << "Array contents: \n"; tree.display_array(); cout << "\nInorder traversal: \n"; tree.inorder_traverse(0); cout << "\nPreorder traversal: \n"; tree.preorder_traverse(0); cout << "\nPostorder traversal: \n"; tree.postorder_traverse(0); cout << endl << endl; } 18