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
Related
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
}
Is there an alternative way to get the max element in a Queue (Java)?
(Please provide alternative approaches )
import java.util.*;
public class MaxQueueElement<E extends Comparable<E>> {
public MaxQueueElement(Queue<E> queue){
E max= queue.peek(); // initialize max with head of queue
for(E e : queue){
if(e.compareTo(max) > 0){
max = e;
}
}
System.out.println(max);
}
}
The get-max operation on a queue can be implemented in amortized O(1) time by maintaining the candidates for the max value in a separate double-ended queue (Deque).
On enqueue (or offer) operation, we check whether there are any elements at the back of the Deque which are lesser in value than the element being enqueued. These values can simply be removed – for these can never be the maximum value going forward.
On dequeue (or poll) operation, we check whether the first element in the Deque is equal to the first element in the regular queue and if yes, remove it too.
The max element is simply the first element of the Deque.
All operations have amortized O(1) time complexity.
Here's an implementation in Java:
public class QueueWithMax<T extends Comparable<T>> {
Queue<T> queue;
Deque<T> cMax; // candidates for Max value
public QueueWithMax() {
queue = new LinkedList<>();
cMax = new LinkedList<>();
}
public void offer(T element) {
queue.offer(element);
while (!cMax.isEmpty() && element.compareTo(cMax.peekLast()) > 0) {
cMax.pollLast();
}
cMax.offerLast(element);
}
public T poll() {
if (cMax.peekFirst().equals(queue.peek()))
cMax.pollFirst();
return queue.poll();
}
public T getMax() {
return cMax.peekFirst();
}
}
The only way to access all elements in a Queue is to use the iterator() method - you can't (generally) access the elements by index (as in, some implementations might, but Queue doesn't inherently).
As such, all you can do is to iterate the elements one at a time, storing the current maximum element. This is exactly what you're doing here.
There is nothing wrong with your algorithm - but the way you've implemented it could be improved:
Don't do this in the constructor of a class - you don't need to construct a new instance of anything, as the maximum value already exists. Do it in a (static) method.
Don't print out the result - that's of no use to man or beast. Return it to the caller.
Handle the cases where the queue is empty and may contain nulls. (Look at the Javadoc of Collections.max for ideas)
I'm taking a computer science class, and we aren't allowed to use the for each loop. I'm not sure if it's the same with you. Note that the for each loop kind of defeats the purpose of a Queue since you want to only be handling the front and end of a queue. In my class specifically, we also want to have the queue be at it's original state before it was passed into the method without using an extra auxiliary data structure. Here's how I would go about it on a test:
public E findMaxQueueElement(Queue<e> queue) { //my test would ask me to return the max value
E max = queue.remove();
queue.add(max); //add it back to the end
for(int i=0; i<queue.size()-1; i++) {
E current = queue.remove();
if (current.compareTo(max) > 0) {
max = current;
}
queue.add(current);
}
return max;
}
With the limitations I provided, this should work. I hope this helps.
You can use Java 8's stream to sort the Queue, it internally uses the same algorithm but will result in less noisy code, e.g.:
public void MaxQueueElement(Queue<E> queue){
Optional<E> max = queue.stream()
.max(Comparable::compareTo);
if(max.isPresent()){
System.out.println(max.get());
}
}
Another approach would be to use PriorityQueue with comparator and get the first element from it. e.g.:
public void MaxQueueElement2(Queue<E> queue){
PriorityQueue<E> pQueue = new PriorityQueue<>((E e1, E e2)->e1.compareTo(e2));
pQueue.addAll(queue);
System.out.println(pQueue.peek());
}
Unless the queue is not some special sorted queue like PriorityQueue, from the algorithmic point of view there is no better way. Since the queue does not have any intrinsic sorting properties, you have to check all the elements of the queue before you find one.
The code is more or less OK. It will fail if the queue contains null. This is normally not the case, but may happen.
The MaxQueueElement construct is somewhat strange.
I think you can also make use of
Collections.max(queue) in case of queue
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 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.
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());
}
}