I've been trying to get the height of the root of 2 trees (same root). I just started working with trees and this way of traversing them without left or right references is causing me some difficulty.
I used the recursion to get to the leaf nodes then I tried to calculate the height via getParent() and a counter.
public int height(){
//code is a little messy but the first number is the height of the root
System.out.print("Height: ");
return height(root);
}
private int height(TNode tn){
if (tn == null) return 0;
int counter = 0;
//recursive call to get to the leaf nodes
for (TNode cn: tn.getChildren()){
height(cn);
}//while at the leaf nodes, count the parent nodes of the leaf nodes
while(tn.getParent() != null){ //if there's a parent
tn = tn.getParent(); //tn becomes its parent
counter+=1;
if(tn.getParent() == null && tn == root){
counter+=1;
}
}
System.out.print(counter + " ");
return counter;
}
The heights of the 2 trees are 4 and 2.
The codes yields
Height: 4 4 4 3 3 4 4 4 3 2 3 3 3 2 2 0
Height: 2 2 2 0
I've tried using stacks and arrays to isolate the 4 and 2 at the beginning but to no avail. Maybe the issue is obvious but maybe my understanding of tree traversal in this manner is a little lacking. Any suggestions would be appreciated.
Related
I want to find the n-th configuration in the solution of the Towers of Hanoi problem given the number of discs and the move's number.
The following code finds the n-th move using tail recursion:
public static String N_th_Move(int k_discs, int move){
return HanoiRec(k_discs, move, "A", "B", "C");
}
private static String HanoiRec(int k_discs, int move, String rod_a, String rod_b, String rod_c) {
int max_n_moves = (int) (Math.pow(2, k_discs) - 1);
int bound =(int) Math.pow(2, k_discs - 1);
if(move > max_n_moves){
return "Not valid";
} else if(move == bound ){
return rod_a + " -> " + rod_b;
} else if(move < bound){
return HanoiRec(k_discs-1, move , rod_a, rod_c, rod_b);
} else {
return HanoiRec(k_discs-1, move - bound, rod_c, rod_b, rod_a);
}
}
How to find the n-th configuration using the same approach?
E.g.:
N_th_configuation(3, 4) #{rod_a: 0, rod_b: 1, rod_c: 2}
ADDED: The binary tree for 3 discs (following the above code):
(0 1 2)
/ \
(1 1 1) (0 2 1)
/ \ / \
(2 1 0) (1 0 2) (1 1 1) (0 3 0)
Where the first number is the number of discs on rod_a, the second on rod_b and the third on rod_c.
The bottom-left leaf is the configuration after the first move and the bottom-right leaf is the configuration after the last move.
I don't find out the relation between all configurations.
The canonical solution for ToH is to alternate two types of moves:
Move the smallest disc to the next rod (with wraparound back to the initial rod)
Make the one legal move that does not include the smallest disc.
wlog (without loss of generality), let's assume that the smallest disc always moves to the next higher-numbered rod (labeled 0, 1, 2).
One result of this algorithm is that odd-numbered discs move higher; even-numbered discs move lower.
Another result is that you can independently determine the disc for any given move number: it's the lowest-value 1 bit in the binary representation of that number. For instance, for the 3-disc problem:
Move binary disc
1 001 1
2 010 2
3 011 1
4 100 3
5 101 1
6 110 2
7 111 1
To find the position matching any move N:
Divide the binaries into separate digits.
Mask off all bit the right-most 1 bit in each.
Add the columns.
Negate the even-numbered columns (to show that the discs move in the opposite direction.
Reduce the totals modulus 3.
The result is a list of columns on which each disc rests.
Inorder: 3 2 1 5 4 6 8 9 7 11 10
Postorder: 1 2 3 4 5 6 9 11 10 7 8
I believe I am on the right track by taking the last postorder value as the root, finding that value in the Inorder list and splitting the tree to the left and the right of that value. From what I've been trying, I was able to come up with this result: It was not formatting correctly so I screenshot it.
Get the last element from the Postorder, this is your root element, then find that element in the Inorder and split the elements in left and right list giving you LEFT: "3 2 1 5 4 6" and RIGHT: "9 7 11 10" then walk the Postorder list and split it once you find the first number before the index of the root element in the Inorder list, in this case this is "6" so walk till 6 and this will give you "1 2 3 4 5 6" and the rest is "9 11 10 7". Then insert those lists in reverse order, e.g.: "6 5 4 3 2 1" and after that "7 10 11 9" this should give you the correct order of the tree.
It is a little tricky, maybe because contradicts a little the brain hemispheres ;-)
The parameters of interest are:
post: an array containing the postorder traversal
lp: left index of post array
rp: right index of post array
in: an array containing the inorder traversal
li: left index of in array
ri: riggh index of ìn array
The procedure is "naturally" recursive. At each recursion, the root always is post[rp]. That is the last visited node (in postorder).
So, the first thing to do is to know the index of the root in the array in. In order to compute that, we scan from li to ri and we search post[rp]. Let i the index of root in the array in. I assume that the tree does not have duplicated keys.
Given the index of root, then
i - li is the number of nodes in the left subtree
ri - i is the number of nodes in the right subtree
Now, in becomes naturally partitioned. The left subtree is between [li, i - 1] and the right subtree is between [i + 1, ri].
What I think is a little confuse is to determine where are the subtrees in post. The left subtree is between [lp, lp + (i - li) - 1] and the right is between [rp - (ri - i), rp - 1]. Take in account the numbers of nodes of each subtree expressed above (in the enumerated list).
With this knowledge we would be ready for designing an algorithm (I write in pseudo-C++, but I think it is very easy to translate to java):
Node * build_postorder(const vector<int> & post, long lp, long rp,
const vector<int> & in, long li, long ri)
{
if (lp > rp)
return nullptr; // we stop recursion when the tree is empty
Node * root = new Node(post[rp]); // Creates the root with key value post[rp]
int i = li;
for (; i <= ri; ++i) // search in inorder array the index of root
if (in[i] == post[rp])
break; // this line must always to execute it (if everything is oK)
LLINK(root) = build_postorder(post, lp, lp + (i - li) - 1, in, li, i - 1);
RLINK(root) = build_postorder(post, rp - (ri - i), rp - 1, in, i + 1, ri);
return root;
}
Good luck!
In an interview, i was given a function:
f(n)= square(f(n-1)) - square(f(n-2)); for n>2
f(1) = 1;
f(2) = 2;
Here n is the level of an n-array tree. f(n)=1,2,3,5,16...
For every level n of a given N-Array I have to print the f(n) node at every level. For example:
At level 1 print node number 1 (i.e. root)
At level 2 print node number 2 (from left)
At level 3 print node number 3 (from left)
At level 4 print node number 5... and so on
If the number of nodes(say nl) at any level n is less than f(n), then have to print node number nl%f(n) counting from the left.
I did a basic level order traversal using a queue, but I was stuck at how to count nodes at every level and handle the condition when number of nodes at any level n is less than f(n).
Suggest a way to proceed for remaining part of problem.
You need to perform Level Order Traversal.
In the code below I am assuming two methods:
One is getFn(int level) which takes in an int and returns the f(n) value;
Another is printNth(int i, Node n) that takes in an int and Node and beautifully prints that "{n} is the desired one for level {i}".
The code is simple to implement now. Comments explain it like a story...
public void printNth throws IllegalArgumentException (Node root) {
if (root == null) throw new IllegalArgumentException("Null root provided");
//Beginning at level 1 - adding the root. Assumed that levels start from 1
LinkedList<Node> parent = new LinkedList<>();
parent.add(root)
int level = 1;
printNth(getFn(level), root);
//Now beginning from the first set of parents, i.e. the root itself,
//we dump all the children from left to right in another list.
while (parent.size() > 0) { //Last level will have no children. Loop will break there.
//Starting with a list to store the children
LinkedList<Node> children = new LinkedList<>();
//For each parent node add both children, left to right
for (Node n: parent) {
if (n.left != null) children.add(n.left);
if (n.right != null) children.add(n.right);
}
//Now get the value of f(n) for this level
level++;
int f_n = getFn(level);
//Now, if there are not sufficient elements in the list, print the list size
//because children.size()%f(n) will be children.size() only!
if (children.size() < f_n) System.out.println(children.size());
else printNth(level, children.get(f_n - 1)); //f_n - 1 because index starts from 0
//Finally, the children list of this level will serve as the new parent list
//for the level below.
parent = children;
}
}
Added solution here
I have used queue to read all nodes at a particular level, before reading the nodes checking if given level(n) is equal to current level then checking size of the queue is greater than f(n) then just read f(n) nodes from queue and mark it as deleted otherwise perform mod operation and delete the node nl%f(n).
The method is supposed to take in two parameters one for depth and one for the integer value of the root of the tree. For Example: for any given N, returns the root reference of a full binary search tree of depth N such that the nodes store the integers 1, 2, …, 2 N+1 – 1. I'm struggling to get this right. Here is what I have:
public static BinaryNode BSTFactory(int top,int depth) {
BinaryNode root=new BinaryNode(null,null,top);
BinaryNode leftChild,rightChild;
if(depth==0){
return root;
}
if(depth==1){
//create 2 children left and right
leftChild=new BinaryNode(null,null,top-1);
rightChild=new BinaryNode(null,null,top+1);
root=new BinaryNode(rightChild,leftChild,top);
return root;
}
if(depth>1){
leftChild=BSTFactory(top-1,depth-1);
rightChild=BSTFactory(top+1,depth-1);
root=new BinaryNode(rightChild,leftChild,top);
return root;
}
return root;
}
First of all, the two parameters of your method depend on each other. For example, BSTFactory(1,3) can't be a full binary tree with a minimal node of 1, since if the root already contains the minimal node, the left sub-tree must be empty (unless you allow negative values in your tree, which is not clear from your question, since you seem to want the tree to store integers starting from 1).
Therefore, I would suggest a wrapper method that would accept only the depth, and calculate the matching root node. We'll see how the two parameters are related later.
Now let's look at some small full binary trees to figure out the recursion :
Depth 0
1
Depth 1
2
1 3
Depth 2
4
2 6
1 3 5 7
Depth 3
8
4 12
2 6 10 14
1 3 5 7 9 11 13 15
What can we learn from these examples?
If we are creating a full binary search tree of depth n :
The root would be 2^n
The left sub-tree will be rooted at root - 2^(n-1)
The right sub-tree will be rooted at root + 2^(n-1)
Therefore, the recusion should be :
public static BinaryNode BSTFactory(int root, int depth)
{
BinaryNode leftChild,rightChild;
if (depth==0){
return new BinaryNode(null,null,root);
} else {
leftChild=BSTFactory(root-Math.pow(2,depth-1),depth-1);
rightChild=BSTFactory(root+Math.pow(2,depth-1),depth-1);
return new BinaryNode(rightChild,leftChild,root);
}
}
Note that in order for this to work (i.e. that your minimal node would be 1), you must call the method with a root and depth such that root=2^depth. To ensure that, lets define a wrapper method :
public static BinaryNode BSTFactory(int depth)
{
return BSTFactory (Math.pow(2^depth),depth);
}
If you call the two parameter method with arbitrary root and depth, you can get binary trees such as :
BSTFactory (6,1)
6
5 7
BSTFactory (1,2)
1
-1 3
-2 0 2 4
There are still full binary trees, but their minimal value is not 1.
I'm having trouble with swapping nodes between two binary trees.
I'm trying to swap the current node with the passed node in the tree, but I can't figure out how; I can only seem to swap the parents of the nodes, but not the nodes themselves.
Can anyone give me some direction?
public void swap(Node node) {
if(this.equals(this.parent.leftChild)){
Node tempNodeR = node.parent.rightChild;
System.out.println("Is a left child");
node.parent.rightChild = this.parent.leftChild;
this.parent.leftChild = tempNodeR;
}
else{
Node tempNodeL = node.parent.leftChild;
System.out.println("Is a right child");
node.parent.leftChild = this.parent.rightChild;
this.parent.rightChild = tempNodeL;
}
}
Calling node2.swap(node4):
Given Tree:
1 3
/ \
2 4
Resulting Tree (unchanged):
1 3
/ \
2 4
Expected Tree:
1 3
/ \
4 2
For each node, the node has a reference to its parent and the parent has a reference to that child. So if you're going to swap two nodes, you need to update four references.
Tree
1 3
/ \
2 4
So here...
1 has a reference that points to 2 that you want to point to 4.
2 has a reference to 1 that should point to 3.
4 has a reference to 3 that should point to 1.
3 has a reference to 4 that should point to 2.
Hope that helps.