From a48615c8f872a5454a0051e9690ae05aad392d22 Mon Sep 17 00:00:00 2001 From: Caleb Fontenot Date: Fri, 2 Feb 2024 19:19:48 -0600 Subject: [PATCH] agh --- .../nb-configuration.xml | 18 + .../ManyToManyFactory.java | 22 +- .../Printed HTMLs/TreeASDV.html | 371 ++++++++++++------ .../projecttrees_calebfontenot/TreeASDV.java | 104 ++--- .../ZIPs/ProjectTrees_CalebFontenot.zip | Bin 0 -> 10203 bytes 5 files changed, 328 insertions(+), 187 deletions(-) create mode 100644 Semester 4/Assignments/MP1_ManyToMany_CalebFontenot/nb-configuration.xml create mode 100644 Semester 4/ZIPs/ProjectTrees_CalebFontenot.zip diff --git a/Semester 4/Assignments/MP1_ManyToMany_CalebFontenot/nb-configuration.xml b/Semester 4/Assignments/MP1_ManyToMany_CalebFontenot/nb-configuration.xml new file mode 100644 index 0000000..6ecd386 --- /dev/null +++ b/Semester 4/Assignments/MP1_ManyToMany_CalebFontenot/nb-configuration.xml @@ -0,0 +1,18 @@ + + + + + + Graal_JDK_20 + + diff --git a/Semester 4/Assignments/MP1_ManyToMany_CalebFontenot/src/main/java/edu/slcc/asdv/caleb/mp1_manytomany_calebfontenot/ManyToManyFactory.java b/Semester 4/Assignments/MP1_ManyToMany_CalebFontenot/src/main/java/edu/slcc/asdv/caleb/mp1_manytomany_calebfontenot/ManyToManyFactory.java index 14794bf..cc64074 100644 --- a/Semester 4/Assignments/MP1_ManyToMany_CalebFontenot/src/main/java/edu/slcc/asdv/caleb/mp1_manytomany_calebfontenot/ManyToManyFactory.java +++ b/Semester 4/Assignments/MP1_ManyToMany_CalebFontenot/src/main/java/edu/slcc/asdv/caleb/mp1_manytomany_calebfontenot/ManyToManyFactory.java @@ -27,7 +27,7 @@ public class ManyToManyFactory { createManyToMany() { return new ManyToMany() { - private HashSet parents = new HashSet(); + //private HashSet parents = new HashSet(); private Map left = new HashMap(); private Map right = new HashMap(); @@ -39,7 +39,9 @@ public class ManyToManyFactory { } /** - * Creates a Many to Many relationship between the parentLeft and the childrenRight. Example for ( Many1 a, Many2 1, 2, 3) it creates --> (a 1) ( a 2 ) ( a 3 ) and ( 1, a ), ( 2, a ), ( 3, a). No duplicate values of Many2 are allowed. + * Creates a Many to Many relationship between the parentLeft and the childrenRight. + * Example for ( Many1 a, Many2 1, 2, 3) it creates --> (a 1) ( a 2 ) ( a 3 ) and ( 1, a ), ( 2, a ), ( 3, a). + * No duplicate values of Many2 are allowed. * * @param parentLeft - exactly one Many1 object. * @param childrenRight - one or more Many2 objects. @@ -53,17 +55,13 @@ public class ManyToManyFactory { public List add(Many1 parentLeft, Many2... childrenRight) { List returnList = new ArrayList(); - // Check to see if values already exist in this many to many object - if (this.left != parentLeft && this.left != null) { - returnList.add((Many2) this.left); - this.left = (Map) parentLeft; - } - if (this.left != childrenRight && this.right != null) { - returnList.add((Many2) this.right); - this.left = (Map) childrenRight; - left.put(parentLeft, Arrays.asList(childrenRight)); - + + // Check for exceptions + if (!childrenRight.equals(parentLeft.getClass())) { + throw new ClassCastException(); } + left.put(parentLeft, new ArrayList(Arrays.asList(childrenRight))); + return returnList; } @Override diff --git a/Semester 4/Assignments/ProjectTrees_CalebFontenot/Printed HTMLs/TreeASDV.html b/Semester 4/Assignments/ProjectTrees_CalebFontenot/Printed HTMLs/TreeASDV.html index f07dcca..20a38e5 100644 --- a/Semester 4/Assignments/ProjectTrees_CalebFontenot/Printed HTMLs/TreeASDV.html +++ b/Semester 4/Assignments/ProjectTrees_CalebFontenot/Printed HTMLs/TreeASDV.html @@ -8,17 +8,18 @@ body {color: #a9b7c6; background-color: #2b2b2b; font-family: monospace; font-weight: bold} pre {color: #a9b7c6; background-color: #2b2b2b; font-family: monospace; font-weight: bold} table {color: #888888; background-color: #313335; font-family: monospace; font-weight: bold} -.number {color: #6897bb} .string {color: #6a8759} -.ST1 {color: #9876aa} -.ST2 {color: #ffc66d} +.number {color: #6897bb} +.ST2 {color: #9876aa} +.ST3 {color: #ffc66d} +.ST1 {color: #8a653b} .comment {color: #808080} .whitespace {color: #505050} -.ST3 {color: #9876aa; font-family: monospace; font-weight: bold; font-style: italic} -.ST5 {color: #ffc66d; font-family: monospace; font-weight: bold; font-style: italic} +.ST4 {color: #9876aa; font-family: monospace; font-weight: bold; font-style: italic} +.ST6 {color: #ffc66d; font-family: monospace; font-weight: bold; font-style: italic} .ST0 {color: #287bde} .literal {color: #cc7832} -.ST4 {font-family: monospace; font-weight: bold; font-style: italic} +.ST5 {font-family: monospace; font-weight: bold; font-style: italic} --> @@ -31,138 +32,163 @@ table {color: #888888; background-color: #313335; font-family: monospace; font-w */ package edu.slcc.asdv.caleb.projecttrees_calebfontenot; +import java.util.ArrayList; +import java.util.Iterator; import java.util.LinkedList; -import java.util.ListIterator; +import java.util.ListIterator; import java.util.Queue; import java.util.Stack; /** * * @author caleb + * @param <T> */ -public class TreeASDV<T extends Comparable> { +public class TreeASDV<T extends Comparable> implements Cloneable { - private Node<T> root; + private Node<T> root; class Node<T> { - T data; - Node<T> leftChild; - Node<T> rightChild; + T data; + Node<T> leftChild; + Node<T> rightChild; } - public boolean insert(T t) { - Node<T> newNode = new Node<>(); - newNode.data = t; + @Override + public Object clone() + { + System.out.println("Cloning..."); + TreeASDV<T> clone = new TreeASDV<T>(); + ArrayList<T> oldData = this.getBreadthFirstArray(); + for (int i = 0; i < oldData.size(); ++i) { + //System.out.println(oldData.get(i)); + clone.insert(oldData.get(i)); + } + return clone; + } - if (root == null) { - root = newNode; + public boolean insert(T t) + { + Node<T> newNode = new Node<>(); + newNode.data = t; + + if (root == null) { + root = newNode; return true; } - Node<T> current = root; + Node<T> current = root; Node<T> parent = null; while (current != null) { parent = current; - if (t.compareTo(current.data) >= 0) { - current = current.rightChild; + if (t.compareTo(current.data) >= 0) { + current = current.rightChild; } else { - current = current.leftChild; + current = current.leftChild; } } // At this point, 'parent' is the node where the new node should be inserted as a child - if (t.compareTo(parent.data) >= 0) { - parent.rightChild = newNode; + if (t.compareTo(parent.data) >= 0) { + parent.rightChild = newNode; } else { - parent.leftChild = newNode; + parent.leftChild = newNode; } return true; } - private void inOrder(Node<T> p) { + private void inOrder(Node<T> p) + { if (p == null) { return; } - inOrder(p.leftChild); - System.out.print(p.data + " "); - inOrder(p.rightChild); + inOrder(p.leftChild); + System.out.print(p.data + " "); + inOrder(p.rightChild); } - public void inOrder() { - inOrder(this.root); - } - - public Node<T> findNode(T t) { - Node<T> currentNode = root; + public Node<T> findNode(T t) + { + Node<T> currentNode = root; while (currentNode != null) { - if (t.compareTo(currentNode.data) == 0) { + if (t.compareTo(currentNode.data) == 0) { return currentNode; - } else if (t.compareTo(currentNode.data) > 0) { - currentNode = currentNode.rightChild; + } else if (t.compareTo(currentNode.data) > 0) { + currentNode = currentNode.rightChild; } else { - currentNode = currentNode.leftChild; + currentNode = currentNode.leftChild; } } return null; } + +public boolean remove(T t) { + // Initialize parent and current nodes for traversal + Node<T> parent = null; + Node<T> current = root; - public boolean remove(T t) { - // Initialize parent and current nodes for traversal - Node<T> parent = null; - Node<T> current = root; - - // Search for the node to be removed - while (current != null && !current.data.equals(t)) { - parent = current; - if (t.compareTo(current.data) > 0) { - current = current.rightChild; - } else { - current = current.leftChild; - } + // Search for the node to be removed + while (current != null && !current.data.equals(t)) { + parent = current; + if (t.compareTo(current.data) > 0) { + current = current.rightChild; + } else { + current = current.leftChild; } - - // If node not found, return false - if (current == null) { - return false; - } - - // Case 1: Node with no children - if (current.leftChild == null && current.rightChild == null) { - if (current == root) { - root = null; // Removing root node - } else if (parent.leftChild == current) { - parent.leftChild = null; // Removing a left child - } else { - parent.rightChild = null; // Removing a right child - } - } // Case 2: Node with one child - else if (current.leftChild == null || current.rightChild == null) { - Node<T> child = (current.leftChild != null) ? current.leftChild : current.rightChild; - if (current == root) { - root = child; // Replace root with its child - } else if (parent.leftChild == current) { - parent.leftChild = child; // Replace parent's left child with the node's child - } else { - parent.rightChild = child; // Replace parent's right child with the node's child - } - } // Case 3: Node with two children - else { - Node<T> successor = getSuccessor(current); - current.data = successor.data; // Replace data with successor's data - // Remove successor node (successor will have at most one right child) - remove(successor.data); - } - - return true; } + // If node not found, return false + if (current == null) { + return false; + } + + // Case 1: Node with no children + if (current.leftChild == null && current.rightChild == null) { + if (current == root) { + root = null; // Removing root node + } else if (parent.leftChild == current) { + parent.leftChild = null; // Removing a left child + } else { + parent.rightChild = null; // Removing a right child + } + } // Case 2: Node with one child + else if (current.leftChild == null || current.rightChild == null) { + Node<T> child = (current.leftChild != null) ? current.leftChild : current.rightChild; + if (current == root) { + root = child; // Replace root with its child + } else if (parent.leftChild == current) { + parent.leftChild = child; // Replace parent's left child with the node's child + } else { + parent.rightChild = child; // Replace parent's right child with the node's child + } + } // Case 3: Node with two children + else { + Node<T> successorParent = current; + Node<T> successor = current.rightChild; + while (successor.leftChild != null) { + successorParent = successor; + successor = successor.leftChild; + } + current.data = successor.data; // Replace data with successor's data + if (successorParent == current) { + successorParent.rightChild = successor.rightChild; + } else { + successorParent.leftChild = successor.rightChild; + } + } + + return true; +} + + // Helper method to find in-order successor of a node - private Node<T> getSuccessor(Node<T> node) { - Node<T> current = node.rightChild; + private Node<T> getSuccessor(Node<T> node) + { + Node<T> current = node.rightChild; Node<T> successorParent = node; Node<T> successor = node; @@ -170,94 +196,172 @@ table {color: #888888; background-color: #313335; font-family: monospace; font-w while (current != null) { successorParent = successor; successor = current; - current = current.leftChild; + current = current.leftChild; } // If the successor is not the right child of the node to be removed, // adjust the successor's parent's leftChild reference - if (successor != node.rightChild) { - successorParent.leftChild = successor.rightChild; - successor.rightChild = node.rightChild; + if (successor != node.rightChild) { + successorParent.leftChild = successor.rightChild; + successor.rightChild = node.rightChild; } return successor; } - public ListIterator<T> listIterator() { - //ListIterator it = new ListIterator<T>(); - return null; + // Inorder ListIterator + public Iterator<T> listIterator() + { + return new InorderIterator(); } - public void breadthFirstTraversal() { - if (root == null) { + private class InorderIterator implements Iterator<T> { + + private Stack<Node<T>> stack; + + public InorderIterator() + { + stack = new Stack<>(); + pushLeft(root); + } + + private void pushLeft(Node<T> node) + { + while (node != null) { + stack.push(node); + node = node.leftChild; + } + } + + @Override + public boolean hasNext() + { + return !stack.isEmpty(); + } + + @Override + public T next() + { + if (!hasNext()) { + throw new java.util.NoSuchElementException(); + } + Node<T> current = stack.pop(); + pushLeft(current.rightChild); + return current.data; + } + + @Override + public void remove() + { + throw new UnsupportedOperationException(); + } + } + + public ArrayList<T> getBreadthFirstArray() + { + ArrayList<T> returnArray = new ArrayList<T>(); + if (root == null) { + return returnArray; + } + Queue<Node<T>> queue = new LinkedList<>(); + + queue.offer(root); + + while (!queue.isEmpty()) { + Node<T> current = queue.poll(); + returnArray.add(current.data); + + if (current.leftChild != null) { + queue.offer(current.leftChild); + } + if (current.rightChild != null) { + queue.offer(current.rightChild); + } + } + return returnArray; + } + + public void breadthFirstTraversal() + { + if (root == null) { return; } Queue<Node<T>> queue = new LinkedList<>(); - queue.offer(root); + queue.offer(root); while (!queue.isEmpty()) { Node<T> current = queue.poll(); - System.out.print(current.data + " "); + System.out.print(current.data + " "); - if (current.leftChild != null) { - queue.offer(current.leftChild); + if (current.leftChild != null) { + queue.offer(current.leftChild); } - if (current.rightChild != null) { - queue.offer(current.rightChild); + if (current.rightChild != null) { + queue.offer(current.rightChild); } } } + @Override + public boolean equals(Object obj) { + return this.getBreadthFirstArray().equals(((TreeASDV) obj).getBreadthFirstArray()); + } - public int height() { - return calculateHeight(root); + public int height() + { + return calculateHeight(root); } - private int calculateHeight(Node<T> node) { + private int calculateHeight(Node<T> node) + { if (node == null) { return 0; } - int leftHeight = calculateHeight(node.leftChild); - int rightHeight = calculateHeight(node.rightChild); + int leftHeight = calculateHeight(node.leftChild); + int rightHeight = calculateHeight(node.rightChild); - return 1 + Math.max(leftHeight, rightHeight); + return 1 + Math.max(leftHeight, rightHeight); } - - public boolean isFullBST() { + + public boolean isFullBST() + { int height = height(); - int nodeCount = countNodes(root); + int nodeCount = countNodes(root); return nodeCount == (1 << height) - 1; // Formula for full binary tree } - private int countNodes(Node<T> node) { + private int countNodes(Node<T> node) + { if (node == null) { return 0; } - return 1 + countNodes(node.leftChild) + countNodes(node.rightChild); + return 1 + countNodes(node.leftChild) + countNodes(node.rightChild); } - - public void inorder() { - if (root == null) { + + public void inOrder() + { + if (root == null) { return; } Stack<Node<T>> stack = new Stack<>(); - Node<T> current = root; + Node<T> current = root; while (current != null || !stack.isEmpty()) { while (current != null) { stack.push(current); - current = current.leftChild; + current = current.leftChild; } current = stack.pop(); - System.out.print(current.data + " "); - current = current.rightChild; + System.out.print(current.data + " "); + current = current.rightChild; } } - public static void main(String[] args) { + public static void main(String[] args) throws CloneNotSupportedException + { TreeASDV<Integer> tree = new TreeASDV<>(); // Insert some elements into the tree tree.insert(5); @@ -269,20 +373,31 @@ table {color: #888888; background-color: #313335; font-family: monospace; font-w tree.insert(8); // Test breadth-first traversal - System.out.println("Breadth-First Traversal:"); + System.out.println("Breadth-First Traversal:"); tree.breadthFirstTraversal(); - System.out.println(); + System.out.println(); // Test height calculation - System.out.println("Height of the tree: " + tree.height()); + System.out.println("Height of the tree: " + tree.height()); // Test if the tree is a full binary tree - System.out.println("Is the tree a full binary tree? " + tree.isFullBST()); + System.out.println("Is the tree a full binary tree? " + tree.isFullBST()); // Test inorder traversal without recursion - System.out.println("Inorder Traversal without Recursion:"); - tree.inorder(); - System.out.println(); + System.out.println("Inorder Traversal without Recursion:"); + tree.inOrder(); + System.out.println(); + System.out.println("array list from breadth traversal"); + System.out.println(tree.getBreadthFirstArray()); + System.out.println("Cloned Tree:"); + TreeASDV<Integer> clonedTree = (TreeASDV<Integer>) tree.clone(); + clonedTree.breadthFirstTraversal(); + System.out.println(); + System.out.println("Does the original tree and the clone tree equal? " + (tree.equals(clonedTree) ? "yes" : "no") ); + tree.insert(3000000); + System.out.println("Does the original tree and the clone tree equal? " + (tree.equals(clonedTree) ? "yes" : "no") ); + tree.remove(5); + tree.breadthFirstTraversal(); } } diff --git a/Semester 4/Assignments/ProjectTrees_CalebFontenot/src/main/java/edu/slcc/asdv/caleb/projecttrees_calebfontenot/TreeASDV.java b/Semester 4/Assignments/ProjectTrees_CalebFontenot/src/main/java/edu/slcc/asdv/caleb/projecttrees_calebfontenot/TreeASDV.java index f84692b..f5eb493 100644 --- a/Semester 4/Assignments/ProjectTrees_CalebFontenot/src/main/java/edu/slcc/asdv/caleb/projecttrees_calebfontenot/TreeASDV.java +++ b/Semester 4/Assignments/ProjectTrees_CalebFontenot/src/main/java/edu/slcc/asdv/caleb/projecttrees_calebfontenot/TreeASDV.java @@ -98,57 +98,65 @@ public class TreeASDV implements Cloneable { return null; } - public boolean remove(T t) - { - // Initialize parent and current nodes for traversal - Node parent = null; - Node current = root; +public boolean remove(T t) { + // Initialize parent and current nodes for traversal + Node parent = null; + Node current = root; - // Search for the node to be removed - while (current != null && !current.data.equals(t)) { - parent = current; - if (t.compareTo(current.data) > 0) { - current = current.rightChild; - } else { - current = current.leftChild; - } + // Search for the node to be removed + while (current != null && !current.data.equals(t)) { + parent = current; + if (t.compareTo(current.data) > 0) { + current = current.rightChild; + } else { + current = current.leftChild; } - - // If node not found, return false - if (current == null) { - return false; - } - - // Case 1: Node with no children - if (current.leftChild == null && current.rightChild == null) { - if (current == root) { - root = null; // Removing root node - } else if (parent.leftChild == current) { - parent.leftChild = null; // Removing a left child - } else { - parent.rightChild = null; // Removing a right child - } - } // Case 2: Node with one child - else if (current.leftChild == null || current.rightChild == null) { - Node child = (current.leftChild != null) ? current.leftChild : current.rightChild; - if (current == root) { - root = child; // Replace root with its child - } else if (parent.leftChild == current) { - parent.leftChild = child; // Replace parent's left child with the node's child - } else { - parent.rightChild = child; // Replace parent's right child with the node's child - } - } // Case 3: Node with two children - else { - Node successor = getSuccessor(current); - current.data = successor.data; // Replace data with successor's data - // Remove successor node (successor will have at most one right child) - remove(successor.data); - } - - return true; } + // If node not found, return false + if (current == null) { + return false; + } + + // Case 1: Node with no children + if (current.leftChild == null && current.rightChild == null) { + if (current == root) { + root = null; // Removing root node + } else if (parent.leftChild == current) { + parent.leftChild = null; // Removing a left child + } else { + parent.rightChild = null; // Removing a right child + } + } // Case 2: Node with one child + else if (current.leftChild == null || current.rightChild == null) { + Node child = (current.leftChild != null) ? current.leftChild : current.rightChild; + if (current == root) { + root = child; // Replace root with its child + } else if (parent.leftChild == current) { + parent.leftChild = child; // Replace parent's left child with the node's child + } else { + parent.rightChild = child; // Replace parent's right child with the node's child + } + } // Case 3: Node with two children + else { + Node successorParent = current; + Node successor = current.rightChild; + while (successor.leftChild != null) { + successorParent = successor; + successor = successor.leftChild; + } + current.data = successor.data; // Replace data with successor's data + if (successorParent == current) { + successorParent.rightChild = successor.rightChild; + } else { + successorParent.leftChild = successor.rightChild; + } + } + + return true; +} + + // Helper method to find in-order successor of a node private Node getSuccessor(Node node) { @@ -360,5 +368,7 @@ public class TreeASDV implements Cloneable { System.out.println("Does the original tree and the clone tree equal? " + (tree.equals(clonedTree) ? "yes" : "no") ); tree.insert(3000000); System.out.println("Does the original tree and the clone tree equal? " + (tree.equals(clonedTree) ? "yes" : "no") ); + tree.remove(5); + tree.breadthFirstTraversal(); } } diff --git a/Semester 4/ZIPs/ProjectTrees_CalebFontenot.zip b/Semester 4/ZIPs/ProjectTrees_CalebFontenot.zip new file mode 100644 index 0000000000000000000000000000000000000000..e4f7249f0ba1456e58fd6e5c70fb7338c75e0284 GIT binary patch literal 10203 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 M`0uTk&mX@1Kfb^HsQ>@~ literal 0 HcmV?d00001