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
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.
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 -> {
...
}
}
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] );
}
}
}
}
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.
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