I have a structure like this of what we'll call Box objects.
Box--+---Box----Box
|
+---Box-+--Box
|
+--Box
|
+--Box
I'm trying to ask the top box object for a list of the leaf node Boxes, which is the 3 box objects in this case.
The box object has a list of its children in an instance variable of type Vector called children.
The number of children can be unlimited.
I've been trying to write a single recursive method to do this, but without success.
One way to do this would be a recursive traversal of the structure. The idea is as follows:
There are no leaf nodes in the empty tree.
In a tree with root r with no children, then r is the only leaf.
In a tree with root r, if r has children, then the leaves of the tree are the leaves of those children.
You could write a recursive traversal with this sort of pseudocode:
void findChildren (Box current, List<Box> found) {
/* Case 1. */
if (current == null) return;
/* Case 2. */
if (current.children.isEmpty()) {
found.add(current);
return;
}
/* Case 3. */
for (Box child: current.children)
findChildren(child, found);
}
Hope this helps!
it has been awhile since I've done Java, so I'm sure this code has plenty of syntax errors, and I hope no one marks me down for it; just trying to give you some algorithm ideas. Hopefully it helps:
vector<Box> getLeaves(Box root)
{
vector<Box> tempList; //vector to hold nodes to check
vector<Box> tempList2; //vector to hold nodes' children
vector<Box> leafList;
bool goflag = true;
tempList.add(root);
while(goflag){
for(int i = 0; i < tempList.size; i++){
if(tempList[i].children.isEmpty()){
leafList.add(tempList[i]);
}
else{
//add all children to tempList2
for(int c = 0; c < tempList[i].children.size; c++){
tempList2.add(tempList[i].children[c])
}
}
if(tempList2.isEmpty()) //no more childs
goflag = false;
else
tempList = tempList2;
tempList2.clear();
}
return leafList;
}
It goes through all the nodes, adding children to the next list to check, and adding leaves to a list to be returned.
There are several ways to write such a function. Here's one approach to work through.
Define a helper function that takes a node and a mutable queue holding nodes.
In that helper function, check if the supplied node's children are empty. If so, add that node to the queue, and return.
If instead the supplied node has any children, call the helper function once for each of the children, passing the child and the same queue reference through.
At the top level, create an empty queue, and call the helper function, passing in the root node and the queue.
When the helper function returns, the queue contains all the leaves in the order they were discovered.
A different approach uses the same depth-first traversal, but the function would return the list of leaves it discovered. These lists would need to be combined for each set of siblings explored, working back up the tree as each function call returns.
Related
I'm trying to implement a binary search tree class in Java with a method that can rebalance the tree if there's a difference in height. I'm trying to do it by first storing the value of the nodes in an List (an attribute of the class).
I then want to take the middle element of this list and assign this to the root of the tree. After this I take the left- and right part of the list and do the same thing recursively to the left- and right children of the root and so on.
My algorithm doesn't seem to work though and I don't understand what I'm doing wrong. I wonder if someone can take a look at my code and explain what the problem is? What I do is basically pass the ordered list of elements of the tree (an attribute of the class) and the root into the function below:
public void build(BinaryNode<E> n,List<E> list) {
int idx = (int)Math.floor(list.size()/2);
if(n!=null) {
n.element = list.get(idx);
} else if(n==null) {
n = new BinaryNode<E>(list.get(idx));
}
if(!list.subList(0,idx).isEmpty()) {
build(n.left,list.subList(0,idx));
}
if(!list.subList(idx+1,list.size()).isEmpty() ){
build(n.right,list.subList(idx+1,list.size()));
}
return;
}
Kind regards,
Java method calls are "call by value". This means changing a parameter (like n in your case) has no effect outside of the method.
Try to define your method like this
public BinaryNode<E> build(List<E> list) { ... }
Try investigating about AVL tree
Some useful links:
https://en.wikipedia.org/wiki/AVL_tree
https://www.geeksforgeeks.org/avl-tree-set-1-insertion/
I need to write a piece of code using the Kruskal algorithm, which in turn needs the Union-Find algorithm.
This includes the methods Make-Set(x), Find-Set(x) and Union(x, y).
I need to implement them using linked lists, but I am not sure of how to start with the Make-Set method.
The Make-Set Method should create a set and make the first element into a key (to compare sets). How exactly would I declare a key using linked lists?
Shortly put: How do I implement this pseudo code for linked lists in Java?
Make-Set(x)
x.p = x
x.rank = 0
Thanks for your help in advance!
I've heard this referred to in the past not as "Union-Find" but as a disjoint set. It isn't exactly a linked list, since the nodes do have a link, but they aren't necessarily linked up in a linear fashion. It's more like a tree where each node has a pointer to its parent and you can walk up the tree to the root.
I don't have much time right now, but here's a quick sketch of how I would implement it in Java:
class Disjoint {
Disjoint next;
Disjoint findSet() {
Disjoint head = this;
if (next != null) {
head = next.findSet();
next = head;
}
return head;
}
void union(Disjoint other) {
Disjoint us = this.findSet();
Disjoint them = other.findSet();
us.next = them;
}
}
Creating an instance is your Make-Set. What you call Find-Set I would call find head or find leader, maybe find identity. I've called it findSet here, though. It walks the chain to find the root of the tree. It also performs an optional operation; it snaps all the links on the way back out of the recursive call so that they all point directly at the root. This is an optimization to keep the chains short.
Finally, Union is implemented just by assigning one root's next pointer to point at the other set. I'm not sure what you intended with rank; if it's the size of the set, you can add a field for that and simply sum them when you union two sets. But you initialize it to 0 for a new set when I would expect it to be initialized to 1.
Two nodes a and b belong to the same set if a.findSet() == b.findSet(). If you need the nodes to carry some data, make the class generic and provide the data to the constructor, and add a getter:
class Disjoint<T> {
Disjoint<T> next;
T data;
public Disjoint(final T data) {
this.data = data;
}
public T getData() {
return data;
}
// rest of class identical except Disjoint replaced with Disjoint<T> everywhere
}
I was just having a simple implementation query.
So I make a BST by using the following code:
class Node{
int data;
Node left=null;
Node right=null;
Node link=null;
public Node(int d)
{
data=d;
}
public void append(int d)
{
Node n=this;
Node nval=new Node(d);
if(n==null)
{
n.data=d;
}
else
{ boolean done=false;
while(!done)
{
if(n.data<=d)
{
if(n.left==null)
{
n.left=nval;
done=true;
System.out.println("Data Entered "+nval.data);
}
else
{
n=n.left;
}
}
else
if(n.data>d)
{
if(n.right==null)
{
n.right=nval;
done=true;
System.out.println("Data Entered "+nval.data);
}
else
{
n=n.right;
}
}
}
}
}
}
Now, I started applying Breadth first and Depth First search on it. I was having genuine issues with doing this.
For DFS, I have to add in the left and right values of the current node that is placed on a stack right? How would I program this? I was having problems with doing this using a Linked List? Can someone tell me how the data structure or pointers should be?
The same thing happens with BFS. In case I wasn't clear before, my main problem is removing an array element and then replacing it with its children.
A Queue (FIFO) generally works well for a BFS. It need not be a Priority Queue, but it often is because giving weights is very common:
Queues typically, but do not necessarily, order elements in a FIFO (first-in-first-out) manner. Among the exceptions are priority queues, which order elements according to a supplied comparator, or the elements' natural ordering, and LIFO queues (or stacks) which order the elements LIFO (last-in-first-out). Whatever the ordering used, the head of the queue is that element which would be removed by a call to remove() or poll(). In a FIFO queue, all new elements are inserted at the tail of the queue. Other kinds of queues may use different placement rules. Every Queue implementation must specify its ordering properties.
Basic "algorithm" rules for BFS with a Queue:
Put initial state(s) in Q (the Queue)
Take the head of the Q (see remove)
Do something with the value taken (e.g. parent -> [child1, child2 ..])
Append any results from step #3 to the tail of the Q (see add)
Go back to step #2 until Q is empty or other end-case is achieved
Arrays are just a PITA to deal with past initialization and iteration. "Slicing" and "resizing" tends to be particularly painful in Java.
for DFS(FILO), u just need to use a stack
for each node, push his right child to the stack first, then push the left child
for BFS(FIFO), u should use queue as #pst mentioned
I'm trying to write a function to traverse a tree with depth first search.
My current algorithm goes something like:
If children
go to first child
If no children
go to next sibling
If no siblings
go to parent
The problem I'm running into is that I can't mark nodes on the tree as having been visited, so when I go to the parent the cycle just resets and it goes to the child again, getting stuck in a loop. Does anyone have any idea as to how I could solve this?
(It's in java using the ANTLR plugin)
EDIT:
Following one of the suggestions I wrote this:
public void traverseTree(Tree tree){
if (tree.getChildCount() > 0){
tree = tree.getChild(0);
traverseTree(tree);
System.out.println(tree.toString());
}
if (tree.getParent().getChild(tree.getChildIndex() + 1) != null){
tree = tree.getParent().getChild(tree.getChildIndex() + 1);
traverseTree(tree);
System.out.println(tree.toString());
}
if (!tree.getParent().toString().contains("ROOT_NODE")){
tree = tree.getParent();
traverseTree(tree);
System.out.println(tree.toString());
}
}
Root node is the name of the root node, but I'm getting a stack overflow error. Anyone have any idea why?
Thanks.
I would use recursion in this case.
class Node {
public List<Node> getChildren() { .... }
public void traverse(Visitor<Node> visitor) {
// If children
// go to first child - by traversing the children first.
for(Node kid: getChildren())
kid.traverse(visitor);
// If no children
// go to next sibling, - by continuing the loop.
visitor.visit(this);
// If no siblings
// go to parent - by returning and letting the parent be processed
}
}
interface Vistor<N> {
public void visit(N n);
}
Using a hash_table map each vertex to boolean indicate whether visited or not
Write a depth first Iterator that keeps track of visited nodes internally. That way the tree doesn't have to change to know that it's being watched.
If "no memory" can be interpreted as O(1) memory, then the change may help:
Remember not only the current node, but also node where you came from
Traverse children only if you didn't came from one of them
I am having difficulty calculating the summation of depths [the sum of the individual depths for all children of the root] for a given BST. I have the total number of nodes for the tree, and I am trying to calculate the average depth for the tree, requiring I have this depth sum.
Recursion and I don't get along very well.. I am finding this problem very difficult. I would like to see a recursive solution though, if possible.
NOTE:
I have created accessors Node.getLeft() and Node.getRight()
You just need to keep a depth counter as you traverse the tree (look up tree traversals if you have to) and add the value of the counter every time you reach a node. Then just divide by the number of nodes.
This looks like homework so I'm not providing a more detailed solution.
Think about how you would go about this canonically by hand if I had presented a picture of a BST to you on a sheet of paper. When you're at a node, what information do you need to keep track of? How does one find the height of a given node?
From here, try to translate this into pseudocode or even straight into Java. If you're having trouble, feel free to comment so users can help you out.
Is this homework? If so tag the question as such.
You could create a method that:
has a node reference and a depth as arguments
increment depth
if node is not a child node call recursively for left and right and update sum accordingly
otherwise return sum + depth
Once you have this devide by the number of children in the tree to get the average depth.
We need to visit all leaf nodes and figure out how deep they are. This suggests:
Give your node-visiting function an extra argument. It needs to know not just where it's going but also how deep it is. Every time it's called, it's called on to go deeper, so your node visitor just has to increment the depth number it got from the caller.
Now one of 2 things can happen:
Either the node you found is a leaf node, i.e. it doesn't have any children; in this case, your visitor needs to return its depth to the caller. Yeah, it just returns the number it got from the caller, + 1.
or it's not a leaf node. In that case, it will have either 1 or 2 children. We need to get those depth reports from our kids back up to the caller, so just return the sum of the depths returned by the children.
By the magic of recursion, the number returned to the root's visitor will be the sum of the depths of all children.
To get an average depth, you'll want to divide this by the number of leaf nodes; which I'd leave to a second traversal to calculate. It could be done in one, but it would be a little more complicated.
Since this is homework, I don't want to just give you an answer. Instead, here's a recursive way to calculate the length of a singly linked list. Hopefully this will demonstrate recursion in a way you can understand, and you can extrapolate from there to solve your BST problem.
public final class LL {
public final int value;
public LL next;
public LL(final int value) {
this.value = value;
}
public void add(final int value) {
if (null == next) {
next = new LL(value);
} else {
next.add(value);
}
}
/**
* Calculate the length of the linked list with this node as its head (includes this node in the count).
*
* #return the length.
*/
public int length() {
if (null == next) {
return 1;
}
return 1 + next.length();
}
public static void main(final String... args) {
final LL head = new LL(1);
head.add(2);
head.add(3);
System.out.println(head.length());
System.out.println(head.next.length());
}
}