How to find a parent of a node in a Binary Tree? - java

I have a tree that was converted from a general tree to a binary tree:
B
/
A
\
D
/ \
/ I
/ /
C H
\ \
E L
\
G
/
F
that means the following:
B is the root, its children are A, D, I
D's children are C, E, G
I's children are H, L
and so on.
Now, I have to write the following method:
public Position<E> parent(Position<E> v)
Where "v" represents one of the letters in the above tree, and this method needs to find its parent.
I've been struggling with this for hours.. Any ideas?

I'm doing the same homework as you...
For the solution,
A parent in our general tree will be a node in our binary tree that has one left child and that the right child of this parent is not equal to our node v.(see the node I)
You can work on this: if the parent of v as a left child then the parent of v will be the last found node with a left child. But the parent must not have a right child so if it has one, you must search for the upper parent of this last node.(see the node I)
Hope this helps

from what you shown:
algorithm is:
start from root
for every node v
every left-child is node v's child so add this child to node v childs list
every right-child is node v's parent's child(or parent of parent until it is a left-child of its parent, then the node you discovered is the child of left-child node's parent's child).
pseudo code for finding a node's parent in actual tree:
enter node.
if node is left child
print its node->parent.
else
while node->parent is right child
node = node->parent
print node->parent.

This is simple; assuming your Node class does not have access to the parent i.e.
class Node{
Node left;
Node right;
int value;
}
All you need to do is to start from the root and traverse over the tree in a pre-order fashion. If you encounter your target node then its parent is one of the last two elements popped from the Stack (why?)
#See Depth First Search

In this kind of binary tree it's simplest to relabel the child pointers as children (left child) and sibling (right child) because that's what they represent. Since you don't have parent pointers, when you find a node that might be a parent, you must pass it on as you search future nodes.
I need to make lots of assumptions because you gave so little information.
If Position is your node type and your desired function is member of a Tree, then then it will look something like:
private Position<E> parentImpl(Position<E> v, Position<E> node, Position<E> parent) {
if (node.equals(v)) {
return parent;
}
for (Position<E> child = v.children; child != null; child = child.sibling) {
Position<E> rtn = parentImpl(v, child, node); // current node is parent
if (rtn != null) {
return rtn;
}
}
return null;
}
Now the function you want just calls this one.
public Position<E> parent(Position<E> v) {
return parentImpl(v, root, null); // Root has no parent.
}
This will return null both when v is not in the tree at all and when it's the root of the tree.

Related

Java Node swaping

i wanna swap 2 nodes in java here is my node class
public class Node {
int freq;
Node left,right,parent;
}
i wanna swap 2 Nodes in my tree
public void swap(Node a, Node b){
Node temp;
temp.freq=a.freq;
temp.parent=a.parent;
temp.left=a.left;
temp.right= a.right;
a.freq=b.freq;
a.left=b.left;
a.right=b.right;
a.parent=b.parent;
b.freq=temp.freq;
b.left=temp.left;
b.right=temp.right;
b.parent=temp.parent;
}
but i found that parent of both nodes becomes b.parent
any hint ????
Looking at your object, Node temp doesn't point to anything besides null. I don't know why your compiler isn't catching this error because using a dot call on a null object will throw a nullpointerexception(e.g. temp.freq; it will have nothing to point to and no internal variables at this point). Make sure that temp points to a new node and try going from there.

Create a full and complete binary tree recursively

Purpose:
I would like to create a full and complete binary tree, which saves a String value in its leaves, recursively.
Example 1:
Let's say you want to save two Strings in your tree. So you will need a root and two leaves.
* <- root node
/ \
v0 v1 <- leaves
Example 2:
Let's say you want to save three Strings in your tree. So you will need a root, two inner Nodes but four leaves, so the tree is still complete.
* <- root node
/ \
+ + <- inner node
/ \
/ \
/ \ / \
v0 v1 v2 v3 <- leaves
Math trickery:
Its fairly straightforward to calculate the specs for the binary tree.
Height: ⌈log2 expectedNumOfStrings⌉
double height = Math.log(expectedNumOfStrings) / Math.log(2);
int roundedHeight = (int) Math.ceil(height);
Number of leaves: 2Height
int numOfLeaves = (int) Math.pow(2, roundedHeight);
Number of inner Nodes: 2h − 1
int numOfInnerNodes = (int) (Math.pow(2, roundedHeight)-1)
Implementation:
Let's implement a couple of classes for this binary tree. We'll need a BinaryTree class.
/**
* Create a complete binary tree recursively depending on the expected leaves.
*/
public class BinaryTree {
private InnerNode root;
private LeafNode current;
public BinaryTree(int expectedNumOfStrings) {
//sets root node
this.root = new InnerNode();
//set inner nodes
root.createInnerNodes(expectedNumOfStrings);
//set leaves
root.createLeaves(expectedNumOfStrings);
//The way things are now the tree isn't created in one go.
//I'll have to traverse it again for the leaves.
}
}
All elements of the tree share a link to the parent (for the root it's null). Let's create a class TreeNode:
public class TreeNode {
private TreeNode parent;
}
Now let's create InnerNode and LeafNode which just extends TreeNode.
public class InnerNode extends TreeNode {
private BinaryTree left;
private BinaryTree right;
//used to set the root node
public InnerNode() {
super.parent = null;
this.left=null;
this.right=null;
}
public InnerNode(InnerNode parent) {
super.parent= parent;
}
public TreeNode createInnerNodes(int expectedValues) {
//recursive magic happens here. But how?
}
}
and
public class LeafNode extends TreeNode {
private String data;
public LeafNode(InnerNode parent) {
super.parent= parent;
}
public LeafNode createLeaves(int numOfLeaves) {
//recursive magic happens here again. But how?
}
}
Questions and Problems
I want to keep the classes as separated as they are and I want to set the Tree up in one go. How to I set up InnerNodes and Leaves at the "same" time?
InnerNode left and InnerNode right are private so I can only access them from within InnerNode. But how do I deal with the leaves then? Can I just pass the root Node though to InnerNode/Leaves in a method?
What is best used for the recursion? Height or Number of corresponding nodes? Or something else entirely?
How do you set the left and right pointer? I mean the objects to which they point don't exist yet, do they?
Am I on the right track? /o\

Symmetric tree algorithm

I need help solving this problem. Only hints please
Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).
Example
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public boolean isSymmetric(TreeNode root) {
if((root == null) || (root.left == null && root.right == null)){return true;}
}
public boolean helper(TreeNode left, TreeNode right){
}
}
The trouble I am having is somehow creating a recursive problem out of this. I am confused because as we branch out, how do I compare one back to the other using helper?
Can someone provide hints?
Recursively call your helper method like following
if (left != null && right != null && left.key == right.key)
return (helper(left.left, right.right)
&& helper(left.right, right.left));
Note that,
we are checking whether the left of the left node and right of the right node is symmetric and right of the left node and left of the right node is symmetric. If both are symmetric then the main tree will be too.
If only root return true.
Else remove root and you will get two sub tress, compare the root with other sub tree. If they are same and have no sub tree return true. Else again remove the root and you will get the two sub tree. Follow the 2nd step again until you will find only one root node. If you find root node on one sub tree but null on other return false.

finding parent in binary search tree

Here is the code to find parent in Binary search tree. I am not able to understand how is it working, as we are never assigning any value to parent other than null. I an new to recursion.
public Node findParent(Type data)
{
return findParent(data, root, null);
}
public Node findParent(Type x, Node node, Node parent)
{
if (node == null) {
return null;
} else if (!(node.data == x)) {
parent = findParent(x, node.left, node);
if (parent == null) {
parent = findParent(x, node.right, node);
}
}
return parent;
}
You are assigning a non null value to parent in the recursive calls :
parent = findParent(x, node.left, node);
----
parent = findParent(x, node.right, node);
----
parent is null only in the initial call (since the root of the tree has no parent).
Each call to findParent gets a value (x), a Node (node) and the parent Node of that Node (parent). If that value is found in the Node, parent is returned, otherwise, you search for that value in the left sub-tree, and if it's still not found, you search for it in the right sub-tree.
Here I put some comments in it. Tell me if it not seems clear. (Recursion is hard to explain)
// The method
public Node findParent(Type x, Node node, Node parent)
{
// if this node is null, return null, cause this
// is not the path you are looking for
if (node == null) {
return null;
// if this is not the node we are looking for,
} else if (!(node.data == x)) {
// We look in the left node.
parent = findParent(x, node.left, node);
// If its not found parent will be null
if (parent == null) {
// So we go look to the right
parent = findParent(x, node.right, node);
}
}
// Eventually we can return the parent.
// If this was the node we were looking for,
// We can return parent without changing it.
// If it was not, this algorithm searched in its subtrees
// If its not there than parent is null.
return parent;
}

How to traverse a level-oriented structure?

I have a linear data structure where every node has a level. The parent node has a level of 1, a node that is child of the parent has a level 2, a node that is child of child has node of 3, another parent node would have a level of 1. e.g. below
<node level=1> //parent node
<node level=2> //child of encountered parent node
<node level=2> //child of encountered parent node
<node level=3> //child of encountered child node
<node level=2> //child of encountered parent node
<node level=1> //parent node
<node level=1> //parent node
<node level=2> //child of encountered parent node
<node level=3> //child of encountered child node
<node level=4> //child of encountered child node
<node level=1> //parent node
Essentially I am trying to build a List. (Open to other suggestions), such that each element in the list is a parent node, each parent node will have list of child nodes, each child node can have list of child nodes etc. Each of the element is a node and all properties are same.
I have tried code by keeping track of the current level but than I am not sure how to properly add a child node, that has child node, that has child node, back to the parent node of the first child node. I feel this might be handled best by recursion but I am have never been able to truly implement recursion in an orderly fashion.
You don't have to think about all the nesting. You only have to think about where you are (as in, what level was the previous entry in the list of nodes) and where the next entry goes.
In this case, the solution lies in the way the tree is read in. Notice in your list of nodes, which is the tree input source, that right after a parent node, the next node is a child. If the node after some node isn't a child of that node (i.e. if its level isn't one level lower), it is the child of one of the previous node's ancestors.
So:
If the level on line n is equal to one plus the level on line n-1, line n holds a child of line n-1.
Otherwise, go up the tree from the node for line n-1 until you find one with a level one less than the level on line n. That ancestor node is the parent of node on line n.
You also don't have to do it recursively.
currLevel = 0;
currNode = root;
do {
node = read();
if (somethingRead()) {
// If this one is one level below the last one, it goes in as a child and we're done
if (node.level == currNode.level + 1) {
currNode.addChild(node);
currNode = node;
} else {
// Otherwise this one has to be at a level above this node's child, so back up
while (node.level >= currNode.level) {
currNode = currNode.parent(); // check for root left out here ...
}
if (node.level == currNode.level + 1) {
currNode.addChild(node);
currNode = node;
} else {
// handle illegal condition in list
}
}
}
} while (moreNodesToRead());
Response to Your Solution
Your solution reflects your reluctance to use a fake node as the root of the tree. That's a design choice one can make. Here is my version of it.
I am a little concerned about how you handle incoming data that is fouled up
A node is presented that is more than one level beyond the one before it.
The first node presented isn't at level 1.
A node has a level of 0 or less (no checks for that below)
Also, I suggest you allow currNode to be null when the current node should be the root. Theoretically it could happen in the while loop that backs up the current node but notice that, at that point in the code, you already know the new node has a level above 1 so currNode should never back up beyond the level 1 nodes. It is reasonable to have it generate a NPE if that assumption is wrong.
I suggest these changes:
Node currNode = null;
List<Root> roots = new ArrayList<Root>();
do {
Node node = generateNode(nodesList.next());
if (node.getLevel() == 1) { //implies root level node
roots.add(node);
currNode = node;
} else if (currNode == null) {
// ... handle misformed input ... first node isn't level 1, ignore it
} else if (node.getLevel() == currNode.getLevel() + 1) {
currNode.childrenList.addChild(node);
node.setParent(currNode);
currNode = node;
} else {
Node savedCurrNode = currNode;
while (node.getLevel() <= currNode.getLevel()) {
currNode = currNode.getParent();
}
if (node.getLevel() == currNode.getLevel() + 1) {
currNode.childrenList.addChild(node);
node.setParent(currNode);
currNode = node;
} else {
// ... handle misformed input ... node level > last node level + 1, ignore it
currNode = savedCurrNode;
}
} while (hasMoreNodes(nodesList));
Printing
I rearranged it a bit and changed some names and responsibilities (listed in comments). Just to belabor a point from above, if the root was just a node you wouldn't need the 'printRoots()' method at all. Just call 'printChildren()' on the fake root node with level set to 0. But it would print one extra line at the top.
(It always makes it easier to read if you indent the output.)
Warning: Not tested.
/** Print all the root nodes, each with any children it may have */
private void printRoots(List<Node> roots) {
for (int j = 0; j < roots.size(); j++) {
Node node = roots.get(j);
printContents(node, 1);
}
}
/** Print one node and any children it might have */
private void printContents(Node node, int level) {
for (int i=1 ; i < level ; ++i) {
print(" ");
}
print(node.toString());
println();
printChildren(node, level+1);
}
/** Print each child of the supplied node. Notice how this is just like getting the
* list of children and calling 'printRoots()'
*//
private void printChildren(Node node, int level) {
for (int i = 0; i < node.getChildrenList().size(); i++) {
Node childNode = node.getChildrenList().get(i);
printContents(childNode, level);
}
}

Categories

Resources