CS Student here practicing on leetcode.
I've been given the following problem:
No idea if this code is any good or not, would appreciate some feedback there as well, but here is what I worked out:
class Solution {
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
TreeNode ret = traverse(root1, root2);
return ret;
}
public TreeNode traverse(TreeNode node1, TreeNode node2){
TreeNode newNode = new TreeNode();
if(node1 == null && node2 == null){
return null;
}
else if(node1 == null){
newNode.val = node2.val;
}
else if(node2 == null){
newNode.val = node1.val;
}
else{
newNode.val = node1.val + node2.val;
newNode.left = traverse(node1.left, node2.left);
newNode.right = traverse(node1.right, node2.right);
}
return newNode;
}
}
Seems to work ok with the sample input given in the example. When I submit the problem, however, I am given this case:
I arrive at the expected answer when I worked it out on paper based on the code I wrote. I am not sure why in this case my code is producing an erroneous result. Help me out here
EDIT: Changed phrasing for clarity
The issue is that you are returning value only when both the nodes are null and not for other case where either node is null. Your code is not going to else statement for "either null" case and it gets returned to the calling function.
Changed code below:
if(node1 == null && node2 == null){
return null;
}
else if(node1 == null){
newNode.val = node2.val;
return node2;
}
else if(node2 == null){
newNode.val = node1.val;
return node1;
}
else{
newNode.val = node1.val + node2.val;
newNode.left = traverse(node1.left, node2.left);
newNode.right = traverse(node1.right, node2.right);
}
Because newNode does not play a role, you can discard and merge directly into roo1 node.
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
if(root1 == null && root2 == null) {
return null;
} else if(root1 == null) {
return root2;
} else if (root2 == null) {
return root1;
} else {
root1.val = root1.val + root2.val;
root1.left = mergeTrees(root1.left, root2.left);
root1.right = mergeTrees(root1.right, root2.right);
}
return root1;
This should work for you.
Could you tell me why this code wont delete a node in a BST? Is there any logical error in my code?
// To delete a node from the BST
public Node deleteNode(Node myRoot, int toDel) {
if (myRoot == null) return null;
else if (toDel < myRoot.data) myRoot.left = deleteNode(myRoot.left, toDel);
else if (toDel > myRoot.data) myRoot.right = deleteNode(myRoot.right, toDel);
else {
// Leaf node
if (myRoot.right == null && myRoot.left == null) {
myRoot = null;
} else if (myRoot.left == null) { // No left child
myRoot = myRoot.right;
} else if (myRoot.right==null){ // No right child
myRoot = myRoot.left;
}
}
return myRoot;
}
NOTE :- This code only deletes the nodes with one child or no child. I am currently working on deleting a node with 2 children so please dont solve that for me.
If 0 children, simply delete node (return null for it).
If there is 1 child, simply replace the node with the child that is not null.
public Node deleteNode(Node myRoot, int toDel) {
if (myRoot == null) {
return null;
} else if (myRoot.data == toDel) {
if (myRoot.left != null) {
return myRoot.left;
} else if (myRoot.right != null) {
return myRoot.right;
} else {
return null;
}
}
...
return myRoot;
}
I implemented recursive algorihtm for deleting nodes in BST, but it seems not to work properly in case in which the node to be deleted has two children. Here is a code for method used to delete nodes:
public boolean delete(int val)
{
Node nodeToBeDeleted = find(val);
if(nodeToBeDeleted != null)
{
//case 1: node has no children
if(nodeToBeDeleted.leftChild == null && nodeToBeDeleted.rightChild == null)
deleteCase1(nodeToBeDeleted);
//case 3: node has two children
else if(nodeToBeDeleted.leftChild != null && nodeToBeDeleted.rightChild != null)
{
deleteCase3(nodeToBeDeleted);
}
//case 2: node has one child
else if(nodeToBeDeleted.leftChild != null)
{
//case 2 where left child should be deleted
deleteCase2(nodeToBeDeleted);
}
else if(nodeToBeDeleted.rightChild != null)
{
//case 2 where right child should be deleted
deleteCase2(nodeToBeDeleted);
}
return true;
}
else
return false;
}
And here deleteCase1, deleteCase2 and deleteCase3 methods:
private void deleteCase1(Node nodeToBeDeleted)
{
//check if node to be deleted is a left or a right child of the parent of the node to be deleted
if(nodeToBeDeleted.parent.leftChild == nodeToBeDeleted)
{
nodeToBeDeleted.parent.leftChild = null;
}
else if(nodeToBeDeleted.parent.rightChild == nodeToBeDeleted)
{
nodeToBeDeleted.parent.rightChild = null;
}
}
Here find method:
public Node find(int val)
{
if(root != null)
{
return findNode(root, new Node(val));
}
return null;
}
private Node findNode(Node search, Node node)
{
if(search == null)
return null;
if(search.data == node.data)
{
return search;
}
else
{
Node returnNode = findNode(search.leftChild, node);
if(returnNode == null)
{
returnNode = findNode(search.rightChild, node);
}
return returnNode;
}
}
minLeftTreversal method:
private Node minLeftTreversal(Node node)
{
if(node.leftChild == null)
return node;
return minLeftTreversal(node.leftChild);
}
Structure of the tree looks like this:
enter image description here
Algorithm works if I delete 75, but if I try to delete 25 it messes up.
Thank you in advance!
Your first if statement in public boolean delete(int val) is missing the { and }
//case 1: node has no children
if(nodeToBeDeleted.leftChild == null && nodeToBeDeleted.rightChild == null)
{ // <---- ADD THIS
deleteCase1(nodeToBeDeleted);
} // <---- AND ADD THIS
//case 3: node has two children
else if(nodeToBeDeleted.leftChild != null && nodeToBeDeleted.rightChild != null)
{
deleteCase3(nodeToBeDeleted);
}
I am doing an assignment, implementing own Binary Search Tree. The thing is, we have our own implementation of Node its parent is not directly accessible.
I have searched for answers, but I do not want to copy the solution entirely and I still don't seem to get it right, though. I miss some cases when the element is not removed.
Can you please help what am I doing wrong?
This is the remove method:
void remove(E elem) {
if(elem != null){
if (root != null && contains(elem)) {
removeFromSubtree(elem, root, null);
}
}
}
void removeFromSubtree(E elem, Node<E> current, Node<E> parent) {
if(elem.less(current.contents)){
if(current.left == null) return ;
removeFromSubtree(elem, current.left, current);
} else if(elem.greater(current.contents)){
if(current.right == null)return;
removeFromSubtree(elem, current.right, current);
} else {
if(current.left != null && current.right != null){
//both children
if(parent == null){
Node<E> n = new Node<>(null, null);
n.left = root;
removeFromSubtree(root.contents, n, null);
root = n.left;
root.setParent(null);
}
E min = subtreeMin(current.right);
current.contents = min;
removeFromSubtree(min, current.right, current);
} else if(current.left != null){
//left child
if (parent == null) {
root = current.left;
current.left.setParent(null);
return ;
}
setParentChild(current, parent, current.left);
} else if(current.right != null){
//right child
if (parent == null) {
root = current.right;
current.right.setParent(null);
return ;
}
setParentChild(current, parent, current.right);
} else {
if (parent == null) {
root = null;
return ;
}
setParentChild(current, parent, null);
}
}
}
Nodes use generic interface
class Node<E extends DSAComparable<E>>
which has just methods for comparation. It looks like this
interface DSAComparable<E extends DSAComparable<E>> {
boolean less(E other);
boolean greater(E other);
boolean equal(E other);
}
I use another methon inside remove that sets node's parent's child, depending if its left child or right child.
void setParentChild(Node<E> node, Node<E> parent,Node<E> value){
if(parent!= null){
if (parent.left == node) {
parent.left = value;
} else {
parent.right = value;
}
if(value!= null) value.setParent(parent);
}
}
Method subtreeMin(Node node) finds the smallest value in a subtree (the most left one)
Understanding your code is not so easy, since it still lacks of details.
I would refer to such an implementation of the Binary Search Tree that you can find online.
See for instance the one from Algorithms, 4th Ed..
I'm trying to search for a node in a binary tree and return in case it's there, otherwise, return null. By the way, the node class has a method name() that return a string with it's name...What I have so far is:
private Node search(String name, Node node){
if(node != null){
if(node.name().equals(name)){
return node;
}
else{
search(name, node.left);
search(name, node.right);
}
}
return null;
}
Is this correct??
You need to make sure your recursive calls to search return if the result isn't null.
Something like this should work...
private Node search(String name, Node node){
if(node != null){
if(node.name().equals(name)){
return node;
} else {
Node foundNode = search(name, node.left);
if(foundNode == null) {
foundNode = search(name, node.right);
}
return foundNode;
}
} else {
return null;
}
}
public Node findNode(Node root, Node nodeToFind) {
Node foundNode = null;
Node traversingNode = root;
if (traversingNode.data == nodeToFind.data) {
foundNode = traversingNode;
return foundNode;
}
if (nodeToFind.data < traversingNode.data
&& null != traversingNode.leftChild) {
findNode(traversingNode.leftChild, nodeToFind);
} else if (nodeToFind.data > traversingNode.data
&& null != traversingNode.rightChild) {
findNode(traversingNode, nodeToFind);
}
return foundNode;
}
Since language doesn't matter much for this question, here's what it looks in C# with pre-order traversal:
public static Node FindNode(Node n, int nodeValue)
{
if (n == null) return null;
if (n.Value == nodeValue) return n;
return FindNode(n.Left, nodeValue) ?? FindNode(n.Right, nodeValue);
}
you should return something if it is found in node.left or node.right
so the else block should be something like that:
else{
Node temp = search(name, node.left);
if (temp != null) return temp;
temp = search(name, node.right);
if (temp != null) return temp;
}
you don't do anything with the result of the recursive calls
Node res = search(name, node.left);
if(res!=null)return res;
res = search(name, node.right);
if(res!=null)return res;
This might be better:
if(node != null){
if(node.name().equals(name)){
return node;
}
else {
Node tmp = search(name, node.left);
if (tmp != null) { // if we find it at left
return tmp; // we return it
}
// else we return the result of the search in the right node
return search(name, node.right);
}
}
return null;
Boolean FindInBinaryTreeWithRecursion(TreeNode root, int data)
{
Boolean temp;
// base case == emptytree
if (root == null) return false;
else {
if (data == root.getData()) return true;
else { // otherwise recur down tree
temp = FindInBinaryTreeWithRecursion(root.getLeft(), data);
if (temp != true)
return temp;
else
return (FindInBinaryTreeWithRecursion(root.getRight(), data));
}
}
}
public static TreeNode findNodeInTree(TreeNode root, TreeNode nodeToFind) {
if (root == null) {
return null;
}
if (root.data == nodeToFind.data) {
return root;
}
TreeNode found = null;
if (root.left != null) {
found = findNodeInTree(root.left, nodeToFind);
if (found != null) {
return found;
}
}
if (root.right != null) {
found = findNodeInTree(root.right, nodeToFind);
if (found != null) {
return found;
}
}
return null;
}
Actually, try to avoid recursivity.
In case you have big tree structure you will get stack overflow error.
Instead of this you can use a list:
private Node search(String name, Node node){
List<Node> l = new ArrayList<Node>();
l.add(node);
While(!l.isEmpty()){
if (l.get(0).name().equals(name))
return l.get(0);
else {
l.add(l.get(0).left);
l.add(l.get(0).right);
l.remove(0);
}
}
return null;
}
public static boolean findElement(Node root, int value) {
if (root != null) {
if (root.data == value) {
return true;
} else {
return findElement(root.left, value) || findElement(root.right, value);
}
}
return false;
}
public TreeNode searchBST(TreeNode root, int val) {
if(root==null || root.val==val) return root;
TreeNode found = (val < root.val) ? searchBST(root.left,val) : searchBST(root.right,val);
return found;
}
View Code on GitHub
private TreeNode findX(TreeNode root, int x) {
if(root == null) return null;
if(root.val == x) return root;
TreeNode left = findX(root.left,x);
TreeNode right = findX(root.right,x);
if(left == null) return right;
return left;
}
Node* search(Node* root,int key){
// If key is found or is NULL
if (root == NULL || root->key == key)
return root;
if (root->key < key)
return search(root->right, key);
return search(root->left, key);
}
For C++ guys:
//search in a binary tree | O(n)
TreeNode* searchBST(TreeNode* root, int val) {
if(!root) return root;
if(root->val == val) return root;
TreeNode* temp = searchBST(root->left, val);
if(!temp){
temp = searchBST(root->right, val);
}
return temp;
}
//search in a BST | O(logn)
TreeNode* searchBST(TreeNode* root, int val) {
if(!root) return root;
if(root->val == val) return root;
if(val < root->val) return searchBST(root->left, val);
return searchBST(root->right, val);
}