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.
Related
I am working on a leetcode problem where I am asked to check whether or not a Binary Search Tree is valid. So far, my solution only passes 58 out 75 test cases. Any pointers on where I went wrong and how to fix it?
Here is the question:
Given a binary tree, determine if it is a valid binary search tree (BST).
Assume a BST is defined as follows:
The left subtree of a node contains only nodes with keys less than the node's key.
The right subtree of a node contains only nodes with keys greater than the node's key.
Both the left and right subtrees must also be binary search trees.
Example 1:
2
/ \
1 3
Input: [2,1,3]
Output: true
Example 2:
5
/ \
1 4
/ \
3 6
Input: [5,1,4,null,null,3,6]
Output: false
Explanation: The root node's value is 5 but its right child's value is 4.
Here is my Solution:
class Solution {
public boolean isValidBST(TreeNode root) {
return isValidHelper(root);
}
public boolean isValidHelper(TreeNode root)
{
if(root == null)
return true;
isValidHelper(root.left);
if(root.left != null && !(root.left.val < root.val) || root.right != null && !(root.right.val > root.val))
return false;
isValidHelper(root.right);
return true;
}
}
Your program fails in cases like this:
5
3 7
1 6
because you only compare the value at the root of the subtrees.
I don't give a fix on purpose. You will learn more finding that out yourself.
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.
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!
So I have to write a function to delete Node with consecutive same items. Like: {1,1,1,2,3,3,4} becomes: {1,2,3,4}
I have written the following code, cant figure out whats wrong with it. It works for the first few items only.
public void deleterepetitive()
{
Node itr = head;
Node itrfront=itr.getNext();
while(itr.getNext()!=null)
{
if(itr.getItem()==itrfront.getItem())
{
itr.setNext(itrfront.getNext());
}
itr = itr.getNext();
itrfront = itrfront.getNext();
}
Any help will be appreciated.
Change the line itrfront = itrfront.getNext(); to itrfront = itr.getNext(); within the while loop. I guess your code breaks after first duplicate omission.
Change the if block as below:(we need check the new next item and not skip it.)
if(itr.getItem()==itrfront.getItem())
{
itrfront = itrfront.getnext();
itr.setNext(itrfront);
continue;
}
Earlier you code was
1st iteration:
1 1 1 1 1 2 3 3 4
^ ^
ITR NExt
duplicate fond so remove node
2nd iteration:
1 1 1 1 2 3 3 4
^ ^
ITR NExt
there are many ways to do this.
i find either stepping through the list from the bottom (starting at the N'th item and iterating back to zero'th item) or taking the collection and inserting it into a Set collection to force the collapse of identical values also works.
cheers
You're not incrementing your iterators correctly, you want itrfront to always be in front of itr, but its actually on top of it:
Let itr be : ^, itrfront be: A, and itr.getNext() be: n, this is what's occurring:
n
1 1 1 2 2 2 2 3
^ A
n
1 1 1 2 2 2 2 3
^ A
n
1 *1* 1 2 2 2 2 3
^
A
n
1 *1* 1 2 2 2 2 3
^
A
n
1 *1* 1 2 2 2 2 3
^
A
where the *1* means garbage collected
What you want to do is something like this:
while(itr.getNext()!=null)
{
while(itr.getItem()==itrFront.getItem())
{
itrfront = itrfront.getNext();
}
itr.setNext(itrfront);
itr = itr.getNext();
itrfront = itr.getNext();
}
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.