Binary Search Tree Delete Node With One Child - binary-search-tree

I have a binary search tree and when I try to do the case where you delete a node with a single child, you delete that node and move the child node in it's place. I have the code for it but it's giving me a bad pointer whenever I do it.
This is the segment of the code
else if((root->Left != NULL) != (root->Right != NULL)){ //Checks if it's a on child node
if(root->Left != NULL){ //If it has a left child, attempts to move the left child to existing node
delete root;
root = root->Left;
}
else{ //If it is right child, attempts to move right child to existing node
delete root;
root = root->Right;
}
}
The struct has values
DATA_TYPE Value;
TreeNode* Left;
TreeNode* Right;
I know I'm allocating it wrong from the debugger, so what's the correct way to move the node?

Edit:
Don't know how I missed it but you're using root right after deleting it.
Edit2:
You need a temporary.
TreeNode* temp = root->Right;
delete root;
root = temp;

Here is a Java implementation for the method
public void removeHalfNodes () {
if ( root == null ) return;
if ( root.left == null && root.right == null ) return;
if ( root.left == null && root.right != null ) root = root.right;
else if ( root.left != null && root.right == null )
root = root.left;
removeHalfNodesRec ( root );
}
public void removeHalfNodesRec ( BinaryTreeNode node ) {
if ( node.left != null ) {
if ( node.left.left == null && node.left.right != null )
node.left = node.left.right;
else if ( node.left.right == null && node.left.left != null )
node.left = node.left.left;
removeHalfNodesRec ( node.left );
}
if ( node.right != null ) {
if ( node.right.left == null && node.right.right != null )
node.right = node.right.right;
else if ( node.right.right == null && node.right.left != null )
node.right = node.right.left;
removeHalfNodesRec ( node.right );
}
}

Related

BST delete - delete "tmp" causes lose of the tree

debug result
Attached my code for trying to delete a node in bst.
If I want to delete node 1, when specifying tmp = del in "if (del_node->l_ == NULL)", and remove tmp, then del is removed as well, and the tree data is lost. how can I solve this issue?
Example tree:
3
/ \
1 5
\
2
all data members and functions are declared public for simplicity.
void BST::DeleteNode(int data) {
BinaryTreeNode* &del_node = BST_Search(head_, data);
if (!del_node->l_ && !del_node->r_)
{
delete del_node;
del_node = nullptr;
return;
}
if (del_node->l_ == NULL)
{
BinaryTreeNode* tmp = del_node;
del_node = del_node->r_;
tmp = nullptr;
delete tmp;
return;
}
if (del_node->r_ == NULL)
{
BinaryTreeNode* tmp = del_node;
del_node = del_node->l_;
delete tmp;
return;
}
else
{
del_node->data_ = smallestRightSubTree(del_node->r_);
}
}
int BST::smallestRightSubTree(BinaryTreeNode* rightroot)
{
// if rightroot has no more left childs
if (rightroot && !rightroot->l_)
{
int tmpVal = rightroot->data_;
BinaryTreeNode* tmp = rightroot;
rightroot = rightroot->r_;
delete tmp;
return tmpVal;
}
return smallestRightSubTree(rightroot->l_);
}
int main()
{
BST bst;
bst.BST_Insert(bst.head_, 3);
bst.BST_Insert(bst.head_, 5);
bst.BST_Insert(bst.head_, 1);
bst.BST_Insert(bst.head_, 2);
bst.DeleteNode(1);
return 0;
}
Thanks for help!
EDIT: this is how tmp and del_node look like after the line "del_node = del_node->r_)" in the condition "if(del->l = null)"
void BST::BST_Insert(BinaryTreeNode*& head, int data) {
if (head == nullptr) {
head = new BinaryTreeNode(data, nullptr, nullptr);
return;
}
if (data > head->data_) {
BST_Insert(head->r_, data);
}
else {
BST_Insert(head->l_, data);
}
}
BinaryTreeNode* BST::BST_Search(BinaryTreeNode* root, int key) {
if (root == nullptr || root->data_ == key)
return root;
if (key > root->data_)
return BST_Search(root->r_, key);
return BST_Search(root->l_, key);
}
If your BST_Search returns a BinaryTreeNode* by value, what is the reference in BinaryTreeNode* &del_node = BST_Search(head_, data); actually referencing? It allocates a new temporary and references that. You probably wanted it to reference the variable that is holding the pointer in the tree so that you can modify the tree.
Your BST_Search would have to look like this:
BinaryTreeNode*& BST::BST_Search(BinaryTreeNode*& root, int key) {
if (root == nullptr || root->data_ == key)
return root;
if (key > root->data_)
return BST_Search(root->r_, key);
return BST_Search(root->l_, key);
}
I can't check whether this actually works, because you didn't provide a self-contained compilable example. But something along these lines.

Why DOESN’T Kotlin smart cast work, even when both are `val`s

In the below code, both the variables are vals, but the smart cast doesn't work even after the null check. Why?
fun SLLNode?.sumListWith(node: SLLNode?, carry: Int = 0): SLLNode? =
when {
this == null && node == null -> if (carry == 0) null else SLLNode(carry)
this == null -> node.also { it!!.value += carry } // Smart cast doesn't work here.
node == null -> this.also { value += carry } // Works here.
else -> {
...
}
}
Smart cast is working!, just make sure that value property is var in class SLLNode:
class SLLNode(var value: Int) // Not val
fun SLLNode?.sumListWith(node: SLLNode?, carry: Int = 0): SLLNode? =
when {
this == null && node == null -> if (carry == 0) null else SLLNode(carry)
this == null -> node.also { it!!.value += carry } // Smart cast doesn't work here.
node == null -> this.also { value += carry } // Works here.
else -> {
...
}
}

Send different metadata to different target streams - PDI

I have two target streams (Matches and mismatches) defined as below:
#Override
public StepIOMetaInterface getStepIOMeta() {
StepMeta stepMeta = new StepMeta();
if (ioMeta == null) {
ioMeta = new StepIOMeta(true, false, false, false, false, true);
StreamInterface matchStream = new Stream(StreamType.TARGET, null, "Matches", StreamIcon.TARGET, null);
StreamInterface mismatchStream = new Stream(StreamType.TARGET, null, "Mismatches", StreamIcon.TARGET, null);
ioMeta.addStream(matchStream);
ioMeta.addStream(mismatchStream);
}
return ioMeta;
}
I want to send different meta data to these two targets. The meta data is received from the previous steps. For match, it needs to be a concatenation of both input streams and for mismatch just the first input stream.
I am stuck on how to define the metadata separately for the two target streams.
Appreciate your help.
List<StreamInterface> targets=getStepIOMeta().getTargetStreams();
List<StreamInterface> infos=getStepIOMeta().getInfoStreams();
if ( info != null )
{
if(targets!=null)
{
if(nextStep.getName().equals(targets.get(0).getStepname()))
{
if ( info != null ) {
for ( int i = 0; i < info.length; i++ ) {
if ( info[i] != null ) {
r.mergeRowMeta( info[i] );
}
}
}
}
if(nextStep.getName().equals(targets.get(1).getStepname()))
{
if ( info != null ) {
if ( info.length > 0 && info[0] != null ) {
r.mergeRowMeta( info[0] );
}
}
}
if(nextStep.getName().equals(targets.get(2).getStepname()))
{
if ( info != null ) {
if ( info.length > 0 && info[0] != null ) {
r.mergeRowMeta( info[1] );
}
}
}
}

Deleting an node in BST

This is not an homework. I am just totally blocked on this. I know what to do but I am having difficulty manipulating the tree. please help.
I am trying to delete and node from an BST. I am able to lookup and find the parent and store it an tree.
package com.test.binarytree;
public class BinaryTreeDelete {
private Node root;
//create null binary tree
public BinaryTreeDelete(){
root = null;
}
//delete
public void delete(int target){
root = delete(root, target);
}
public Node delete(Node node, int target){
NodeWithParent temp = lookupFindParent(root, null, target);
if( node == null){
return null;
}
else{
if( node.left == null || node.right == null) //leaf node
{
//WHAT DO I DO HERE
//temp.parent.left = null;
//temp.parent.right = null;
//return null;
}
if( node.left != null && node.right == null ) //one child only on left
{
//WHAT DO I DO HERE
}
if( node.right != null && node.left == null ) //one child only on right
{
//WHAT DO I DO HERE
}
if( node.left != null && node.right != null ) //two children
{
//WHAT DO I DO HERE
}
}
return null;
}
private NodeWithParent lookupFindParent(Node node, Node parentNode, int target){
if( node == null ){
return null;
}
if( node.data == target){
return new NodeWithParent(node, parentNode);
}
else if( node.data > target ){
parentNode = node;
return lookupFindParent(node.left, parentNode, target);
}
else{
parentNode = node;
return lookupFindParent(node.right, parentNode, target);
}
}
//insert
public void insert(int data){
root = insert(root, data);
}
public Node insert (Node node, int data){
if(node == null){
node = new Node(data);
}
else{
if( data <= node.data ){
node.left = insert(node.left, data);
}
else{
node.right = insert(node.right, data);
}
}
return node;
}
//print tree
public void printTree(){
printTree(root);
System.out.println();
}
//print tree
private void printTree(Node node) {
if (node == null) return;
// left, node itself, right
printTree(node.left);
System.out.print(node.data + " ");
printTree(node.right);
}
//node class
public static class Node{
Node left;
Node right;
int data;
Node(int newNode){
data = newNode;
left = null;
right = null;
}
}
//node class
public static class NodeWithParent{
Node current;
Node parent;
NodeWithParent(Node current, Node parent){
this.current = current;
this.parent = parent;
}
}
public static void main(String[] args) {
BinaryTreeDelete bt = new BinaryTreeDelete();
//insert with inserts - tree increases on right if inserted in order
bt = new BinaryTreeDelete();
bt.insert(5);
bt.insert(3);
bt.insert(7);
bt.insert(1);
bt.insert(4);
bt.insert(6);
bt.insert(9);
bt.printTree();
//bt.delete(3);
//bt.delete(4);
//bt.delete(6);
bt.delete(9);
//bt.delete(5);
bt.printTree();
}
}
I'm going to provide you the logic (that means you have to write the code yourself) of how to delete a node in a BST.
There are three cases.
Node to be deleted has both left and right child as null: Delete the node and make the parent point to null.
Node to be deleted has either left or right child (but not both) as null: Delete the node but make sure that the parent points to the valid child of the to-be-deleted node.
Node to be deleted has nether left child nor right child as null: In this case, you have to find the next greater element of the to-be-deleted node. This next greater element is the least element of the right subtree of the to-be-deleted node. Since this is the least element, it has at least one of its child as null. So swap the values of the to-be-deleted node with the next greater node. After you swap, delete this next greater node using points 1 and 2 (whichever is fitting to the situation). Now, why the next greater node and not any node. Because if you replace a node with its next greater node, the BST remains a BST. Try it out in an example and it will be clear.

QueryOver - JoinQueryOver problems

i How to use queryover (Join) for same table...example
if (!string.IsNullOrEmpty(ufResidencia) ||
!string.IsNullOrEmpty(cidadeResidencia))
{
EnderecoProspect endPros = null;
TipoEndereco tipoEnd = null;
query
.JoinQueryOver<EnderecoProspect>(x => x.Enderecos,()=> endPros)
.And(()=> endPros.Uf ==ufResidencia)
.JoinQueryOver<TipoEndereco>(x => x.TipoEndereco,()=> tipoEnd)
.And(()=> tipoEnd.Descricao != "Fazenda");
}
if (!string.IsNullOrEmpty(ufFazenda) ||
!string.IsNullOrEmpty(cidadeFazenda))
{
EnderecoProspect endPros1 = null;
TipoEndereco tipoEnd1 = null;
query
.JoinQueryOver<EnderecoProspect>(x => x.Enderecos,()=> endPros1)
.And(()=> endPros1.Uf ==ufFazenda)
.JoinQueryOver<TipoEndereco>(x => x.TipoEndereco,()=> tipoEnd1)
.And(()=> tipoEnd1.Descricao == "Fazenda");
}
When I try to run I get the message that the path is duplicated. Im using alias correct? what problem? havy ideal? exception is "duplicate association path"
I managed to solve with LINQ to NHibernate ... there is the example for all ...
var q =
from c in Context.Query<Prospect>()
join o in Context.Query<EnderecoProspect>() on c.Identificacao equals o.Prospect.Identificacao
join e in Context.Query<TipoEndereco>() on o.TipoEndereco.Identificacao equals e.Identificacao
join a in Context.Query<EnderecoProspect>() on c.Identificacao equals a.Prospect.Identificacao
join b in Context.Query<TipoEndereco>() on a.TipoEndereco.Identificacao equals b.Identificacao
where (
(
(o.Uf == ufFazenda || ufFazenda == null) &&
(o.Cidade == cidadeFazenda || cidadeFazenda == null)
) && e.Descricao == "Fazenda"
)
&&
(
(
(a.Uf == ufResidencia || ufResidencia == null) &&
(a.Cidade == cidadeResidencia || cidadeResidencia == null)
) && b.Descricao != "Fazenda"
)
Now I can sleep a little more until ...ehehehe...see you