Working on an assignment. Taking classes online and I've emailed my prof with the same question but I'm hoping to get a quicker response from you wonderful people here (as I only have 2 hours per day that I can work on school and Ive hit a roadblock).
Assignment is to finish the code for a binary search tree and blah blah implement some stuff.
I'm hung up on one chunk of code that I just cant understand.
This is a code snippet from the LinkedBinaryTree class that was provided.
LinkedBinaryTree relies on a BinaryTreeNode class for the nodes.
public class LinkedBinaryTree<T> implements BinaryTreeADT<T>, Iterable<T>
{
protected BinaryTreeNode<T> root;
protected int modCount;
}
//Constructors
public LinkedBinaryTree()
{
root = null;
}
public LinkedBinaryTree(T element)
{
root = new BinaryTreeNode<T>(element);
}
public LinkedBinaryTree(T element, LinkedBinaryTree<T> left,
LinkedBinaryTree<T> right)
{
root = new BinaryTreeNode<T>(element);
root.setLeft(left.root);
root.setRight(right.root);
}
This is primarily what I fail to grasp.
root.setLeft(left.root);
root.setRight(right.root);
What is .root and how does that work.
The variable is being used in two places? is this some kind of recursion/magic that I just haven't encountered yet? (And currently fail to understand) If so, I will get reading let me know and point me in the right direction.
I will post the code for the BinaryTreeNode methods below. I don't understand these parameters that are being passed.
root is a variable of the type BinaryTreeNode but in its use it is passing a LinkedBinaryTree either left or right as the parameters for a method that requires a variable of type BinaryTreeNode
public class BinaryTreeNode<T>{
protected T element;
protected BinaryTreeNode<T> left, right;
//Constructors
public BinaryTreeNode(T obj)
{
element = obj;
left = null;
right = null;
}
public BinaryTreeNode(T obj, LinkedBinaryTree<T> left, LinkedBinaryTree<T> right)
{
element = obj;
if (left == null)
this.left = null;
else
this.left = left.getRootNode();
if (right == null)
this.right = null;
else
this.right = right.getRootNode();
}
And the methods in question
public void setLeft(BinaryTreeNode<T> node)
{
left = node;
}
public void setRight(BinaryTreeNode<T> node)
{
right = node;
}
This is a binary tree, as mentioned.
Every not-null node has a node to the left and right. Sometimes the value of nodes are null.
As explained in the comments of the question, you are calling the root variable from the type BinaryTreeNode. It would only make sense because the code was written.
Related
I'm trying to write my own CustomLinkedList<E> to rapidly pass labs where I need to implement stacks and queues. I can pass the labs without this class (since I don't need to implement iterable at all), but I would like to grasp the concept since I'm learning java anyway.
I've got most of things running and tested now, but I couldn't make iterator to work properly yet.
The first approach was "post-increment", e.g.:
E result = current.getValue();
current = current.getNext();
return result;
which I found to be broken, because then when I reach the end of the list, I won't be able to get back. My hasNext() just checks if the current is null, thus the ability to go back is lost.
The second approach was to add dummy Node on creation, to model the beginning. It had an issue of determining if I'm at the beginning of the list, since with this approach I don't know where is the beginning until its too late.
Iterator(Node root)
{
current = new Node(null, null, root);
}
public E next()
{
//checks and stuff
current = current.getNext();
return current.getValue();
}
So, question is: is it possible to implement ListIterator<> only knowing the current element? If yes, some code scratches would be great.
EDIT:
Node:
private class Node
{
private Node prev;
private T value;
private Node next;
Node(Node prev, T value, Node next) {
this.setPrev(prev);
this.setValue(value);
this.setNext(next);
}
//getters and setters
}
CustomLinkedList<E>:
public class CustomLinkedList<T> implements Iterable<T>{
private class Node {/**/}
private class Iterator implements java.util.ListIterator<T> {
Node current;
public Iterator(Node root) //from the first approach
{
current = root;
}
//other methods
}
Node root;
int size;
//Object methods, and some basic Collection methods
}
I would do something like this:
public class CustomLinkedList<T> implements Iterable<T>{
private class Node {/**/}
private class Iterator implements ListIterator<T> {
Node next, previous;
Iterator() {
next = root;
previous = null;
}
public boolean hasNext() {
return next != null;
}
public T next() {
if ( ! hasNext()){
throw new NoSuchElementException();
}
previous = next;
next = next.getNext();
return previous;
}
public boolean hasPrevious() {
return previous != null;
}
public T previous() {
if ( ! hasPrevious() ){
throw new NoSuchElementException();
}
next = next.getPrevious();
previous = next.getPrevious();
return next;
}
}
Node root;
int size;
//Object methods, and some basic Collection methods
}
This doesn't implement the other methods of the ListIterator interface, but you get the idea. You need to think of your iterator's cursor as being in-between the previous and the next element, not on one of them. For a proper implementation, see Jorn Vernee's link.
I realize that there are a few good threads already existing which discuss how to implement a linked list in Java, however I can't seem to find one which does not use a constructor like this,
public LinkList() {
Link = null;
}
or something along these lines. However, I have not done this in my code, and therefore I am having trouble with writing a few of the methods.
I have a class called Link which contains the following code, note without any constructor like the one displayed above:
public class Link {
private Link next = null;
private String value = null;
public Link getNext(){
return next;
}
public void setNext(Link nextLink){
next = nextLink;
}
public String getValue(){
return value;
}
public void setValue(String aValue){
value = aValue;
}
}
and then I have my LinkedList class, which contains the following code:
public class LinkedList {
private Link head = null;
private Link tail = null;
public Link getHead(){
return head;
}
public void setHead(Link aLink){
head = aLink;
}
public Link getTail(){
return tail;
}
public void setTail(Link aLink){
tail = aLink;
}
public boolean isEmpty(){
return(head == null && tail == null);
}
public void addLast(String aString){
Link link = new Link();
link.setValue(aString);
//tail.setNext(link);
if(isEmpty()){
head = link;
}else{
tail.setNext(link);
}
tail = link;
}
public void addFirst(String aString) {
Link link = new Link();
link.setValue(aString);
if(isEmpty()){
tail = link;
}else{
head.setNext(link);
}
head = link;
}
public Link removeFirst(){
Link temp = head;
head = temp.getNext();
temp.setNext(null);
return temp;
}
}
My addFirst Method, and my isEmpty Method both seem to be working but my addLast and removeFirst Methods are not. I have drawn pictures, looked at pseudo code, and searched around the internet, but I just cannot seem to figure this out.
I need to know how to get my addLast and removeFirst methods working without having to add in the constructor at the beginning like all the rest of the example code I keep seeing.
Here are the Tests they need to pass:
#Test
public void testRemoveFirst(){
list.addFirst("three");
list.addFirst("two");
list.addFirst("one");
assertTrue("one".equals(list.removeFirst()));
assertTrue("two".equals(list.removeFirst()));
assertTrue("three".equals(list.removeFirst()));
}
#Test
public void testAddLast(){
list.addFirst("three");
list.addFirst("two");
list.addFirst("one");
assertTrue( "three".equals(list.removeLast()));
assertTrue( "two".equals(list.removeLast()));
assertTrue( "one".equals(list.removeLast()));
assertNull(list.removeLast());
}
One change in your code is needed: you want the new link to point to your old head as "next" (not the other way round) because you want to insert it at the beginning.
public void addFirst(String aString) {
Link link = new Link();
link.setValue(aString);
if (isEmpty()) {
tail = link;
} else {
link.setNext(head);
}
head = link;
}
Also, you need to change your tests as now you compare String to Link instances instead of String to String
assertTrue("one".equals(list.removeFirst().getValue()));
assertTrue("two".equals(list.removeFirst().getValue()));
assertTrue("three".equals(list.removeFirst().getValue()));
After those changes the test passes for me (the first one, you didn't implement removeLast method for the second one).
You do not need a constructor to assign null, 0 and false to object fields. Fields get these values automatically. Simply remove the constructor that only does such assignments and it will be no any difference in execution.
You can also assign other default values like int a = 17 directly in declaration, and you can also include expressions like int b = a + 1 assuming that the field a has been declared before. But you cannot pass parameters that must have different values for different instances. This is what the constructor is for.
You may still have other bugs remaining but it will be no constructor to blame.
Most often developers simply use the ready solution, LinkedList.
How would I go around recursively traversing and storing a directory structure? I'm writing an app to load up two folders, traverse their structure, show the differences in a GUI, and synchronize the two if prompted to do so.
Background: I get the basic principle(use a tree; if a file, append it to the calling dir, if a dir, append and recursively call the function on it), but all the implementations I found are just a little bit off from what I need, or they spit out a NullPointerException which I can't fix, as I don't understand what exactly they do. I think I'm stuck on a technicality or a quirk somewhere in the recursive calls or in creating child nodes.
Edit:
This is a node class i copied from somewhere. I recently deleted my old putIntoTree function, and I'm currently working on a new one. I'm stuck on how exactly the children/parent creation works.
import java.nio.file.Path;
import java.util.*;
abstract class TreeNode implements Iterable<TreeNode> {
private Set<TreeNode> children;
public Path path;
public TreeNode(Path path) {
children = new HashSet<TreeNode>();
this.path = path;
}
public boolean addChild(TreeNode n) {
return children.add(n);
}
public boolean removeChild(TreeNode n) {
return children.remove(n);
}
public Iterator<TreeNode> iterator() {
return children.iterator();
}
}
Edit: I'm trying to get this tree structure to work in there, but I'm a bit baffled at how exactly pointy brackets and generics work. It says "cannot resolve symbol[whatever is after the in my own attempt at defining a method]"
public class Tree<T> {
private Node<T> root;
public Tree(T rootData) {
root = new Node<T>();
root.data = rootData;
root.children = new ArrayList<Node<T>>();
}
public static class Node<T> {
private T data;
private Node<T> parent;
private List<Node<T>> children;
}
}
In C# I found a method that was pretty sweet that allowed you to get all the descendants and all of THEIR descendants from a specified control.
I'm looking for a similar method for JavaFX.
I saw that the Parent class is what I want to work with since it is the class from which all Node classes that bear children are derived.
This is what I have so far (and I haven't really found anything on google with searches like "JavaFX get all nodes from a scene"):
public static ArrayList<Node> GetAllNodes(Parent root){
ArrayList<Node> Descendents = new ArrayList<>();
root.getChildrenUnmodifiable().stream().forEach(N -> {
if (!Descendents.contains(N)) Descendents.add(N);
if (N.getClass() == Parent.class) Descendents.addAll(
GetAllNodes((Parent)N)
);
});
}
So how do I tell if N is a parent (or extended from a parent)? Am I doing that right? It doesn't seem to be working... It's grabbing all the nodes from the root (parent) node but not from the nodes with children in them. I feel like this is something that's probably got an answer to it but I'm just asking the question... wrong. How do I go about doing this?
public static ArrayList<Node> getAllNodes(Parent root) {
ArrayList<Node> nodes = new ArrayList<Node>();
addAllDescendents(root, nodes);
return nodes;
}
private static void addAllDescendents(Parent parent, ArrayList<Node> nodes) {
for (Node node : parent.getChildrenUnmodifiable()) {
nodes.add(node);
if (node instanceof Parent)
addAllDescendents((Parent)node, nodes);
}
}
I use this,
public class NodeUtils {
public static <T extends Pane> List<Node> paneNodes(T parent) {
return paneNodes(parent, new ArrayList<Node>());
}
private static <T extends Pane> List<Node> paneNodes(T parent, List<Node> nodes) {
for (Node node : parent.getChildren()) {
if (node instanceof Pane) {
paneNodes((Pane) node, nodes);
} else {
nodes.add(node);
}
}
return nodes;
}
}
Usage,
List<Node> nodes = NodeUtils.paneNodes(aVBoxOrAnotherContainer);
This source code uses the references of the existing nodes. It does not clone them.
This seems to get ALL nodes.
(In Kotlin)
fun getAllNodes(root: Parent): ArrayList<Node> {
var nodes = ArrayList<Node>()
fun recurseNodes(node: Node) {
nodes.add(node)
if(node is Parent)
for(child in node.childrenUnmodifiable) {
recurseNodes(child)
}
}
recurseNodes(root)
return nodes
}
I'd like to add to Hans' answer, that you have to check if parent is a SplitPane. Because SplitPanes have an empty list using getUnmodifiableChildren(), you'll have to use getItems() instead. (I do not know if there are other parents that do not provide their children via getUnmodifiableChildren(). SplitPane was the first I found...)
Unfortunately this won't get subnodes for most container components. If you try a TabPane as parent, you'll find no children, but you can find tabs in it with getTabs(). The same is with SplitPane and other. So every container will require a specific approach.
You could use node.lookupAll("*"), but it also doesn't look inside.
The solution could be a "Prototype" pattern - creating a meta class with common interface of getChildren() method, which is realized in subclasses - one for each type.
Approach example is given here.
This works for me:
public class FXUtil {
public static final List<Node> getAllChildren(final Parent parent) {
final List<Node> result = new LinkedList<>();
if (parent != null) {
final List<Node> childrenLvl1 = parent.getChildrenUnmodifiable();
result.addAll(childrenLvl1);
final List<Node> childrenLvl2 =
childrenLvl1.stream()
.filter(c -> c instanceof Parent)
.map(c -> (Parent) c)
.map(FXUtil::getAllChildren)
.flatMap(List::stream)
.collect(Collectors.toList());
result.addAll(childrenLvl2);
}
return result;
}
}
I wrote this n-array tree class. I want to write a method to add a child to a specific node in my tree.
First I should search my tree to find the father then add the child to that node children.
I don't know how I should declare my method
public class FamilyNode {
public String name;
public String Family;
public String sex;
public FamilyNode Father;
public FamilyNode Mother;
public FamilyNode Spouse=null;
public String status="alive";
public int population;
public ArrayList<FamilyNode> children=new ArrayList<FamilyNode>() ;
public FamilyNode(String firstname,String lastname,String sex1){
this.name=firstname;
this.Family=lastname;
this.sex=sex1;
this.population=this.children.size()+1;
}
public void SetParents(FamilyNode father,FamilyNode mother){
this.Father=father;
this.Mother=mother;
}
public void SetHW(FamilyNode HW){
this.Spouse=HW;
}
public int Number (){
int number_of_descendants = this.population;
if(this.Spouse!=null) number_of_descendants++;
for(int index = 0; index < this.children.size(); index++)
number_of_descendants = number_of_descendants+ this.children.get(index).Number();
return number_of_descendants;
}
public void AddChild(FamilyNode Father,FamilyNode child){
//the code here
}
}
I answered one of your related questions yesterday so let's continue with the code I posted :)
public class FamilyNode {
// ...
// ...
public FamilyNode findNodeByName(String nodeName){
if(name.equals(nodeName)){
// We found a node named nodeName, return it
return this;
}
// That's not me that you are looking for, let's see my kids
for(FamilyNode child : children){
if(child.findNodeByName(nodeName) != null)
// We found what we are looking, just return from here
return child;
}
// Finished looping over all nodes and did not find any, return null
return null;
}
public void addChild(FamilyNode child){
children.add(child);
}
}
Basically, you need to find the node you are looking for (by name in this case) and that can be done by the findNodeByName above. Once the node is found, add one child to it.
Use this code like this:
FamilyNode root = ...;
FamilyNode node = root.findNodeByName("Parent");
if(node != null) node.addChild(...);
NOTE
If you want to debug and visit all your tree nodes, use this method:
public FamilyNode findNodeByName(String nodeName){
System.out.println("Visiting node "+ name);
// That's not me that you are looking for, let's see my kids
for(FamilyNode child : children){
child.findNodeByName(nodeName)
}
// Finished looping over all nodes and did not find any, return null
return null;
}
This isn't exactly a tree, as children have potentially two parents rather than just one. It's a directed graph.
It would be good to change your variable and method names to be consistent with the usual Java convention of starting with a lowercase character.
In the interest of data consistency, you might consider making the addChild method something that simply adds to the list of children for the current node, but in your setParents method, update the child lists of both parents, adding the current node as a child there, by calling father.addChild(this) and mother.addChild(this) (protecting against them being null of course).
If the parents can be changed when they're previously set (presumably in error), you'll also need to remove the current node from previously set parents. For this, you might need a removeChild(FamilyNode child) method. Again for data consistency, this method should probably also set the appropriate parent field in the child node to null.