BST节点删除-指针未正确删除?

时间:2019-02-09 04:56:21

标签: c++ pointers binary-search-tree

我正在一个简单的3节点二进制搜索树上运行一些测试。根节点的值为1,其左子节点和右子节点的值分别为0和2。

这是源代码(3个文件):

文件名:bst.cpp

#include <iostream>
#include "bst.h"

template <typename T> 
void binary_search_tree<T>::insert(const T val2ins)
{
   num_nodes++;

   if(!root)
   {
      root = new tree_node<T>(val2ins, nullptr, nullptr, nullptr);
      return;
   }

   //loop from root until we find where to insert val2ins; seek to find a suitable parent with a nullptr
   auto curr_node = root;
   tree_node<T> *prev_node = nullptr;
   while(curr_node)
   {
      prev_node = curr_node;
      if(val2ins >= curr_node->val)        //assign equalities on right children
      {
         curr_node = curr_node->right;
      }
      else
      {
         curr_node = curr_node->left;
      }
   }

   //prev_node is the parent of curr_node
   curr_node = new tree_node<T>(val2ins, prev_node, nullptr, nullptr);

   //curr_node now points to a tree_node that contains a pointer to to the previous node
   //we also need to go to previous_node and set its left/right children to curr_node
   if(curr_node->val < prev_node->val)
   {
      prev_node->left = curr_node;
   }
   else
   {
      prev_node->right = curr_node;
   }
}

template <typename T> 
tree_node<T> *binary_search_tree<T>::get_root()
{
   return root;
}

文件名:bst.h

#ifndef _BST_H_
#define _BST_H_

template<typename T>
struct tree_node
{
   T val;
   tree_node *parent;
   tree_node *left;
   tree_node *right;

   tree_node() : val(0), parent(nullptr), left(nullptr), right(nullptr) {}
   tree_node(T val2ins, tree_node *p_ptr, tree_node *l_ptr, tree_node *r_ptr) 
   {
      val = val2ins;
      parent = p_ptr;
      left = l_ptr; 
      right = r_ptr;
   }
};

template<typename T>
class binary_search_tree
{
private:
   int num_nodes;
   tree_node<T> *root;
   //helper function for deletion
   void transplant(const tree_node<T> *node2replace, const tree_node<T> *node2insert);

public:
   binary_search_tree() : num_nodes(0), root(nullptr) {}
   binary_search_tree(int N, tree_node<T> *ptr) : num_nodes(N), root(ptr) {}
   void insert(const T val2ins);
   void delete_node(const tree_node<T> *node2del);

   tree_node<T> *get_root();


   // void 
};

#endif

文件名:main.cpp

#include <iostream>
#include "bst.h"
#include "bst.cpp"

template <typename T> 
class Solution {
public:
    tree_node<T> *trimBST(tree_node<T> *root, int L, int R) {
        search_and_delete(root, L, R);
        return root;
    }

    void search_and_delete(tree_node<T> *&node, const int L, const int R)
    {
        if(!node)
        {
            return;
        }
        if(node && node->val >= L && node->val <= R)
        {
            trimBST(node->right, L, R);

            std::cout << node->left << std::endl;
            trimBST(node->left, L, R);
            std::cout << node->left << std::endl;
            std::cout << node->left << std::endl;
        }
        else if(node && node->val > R) 
        {
            //delete right sub tree
            //then check left sub tree
            //Also need to delete current node and link left (if needed)
            //this can be done by simply setting current node to its left
            if(node->left == nullptr && node->right == nullptr)
            {
                delete node;
                node = nullptr;
                return;
            }

            if(node->right)
            {
                delete node->right;
                node->right = nullptr;
            }
            if(node->left)
            {
                node = node->left;
            }
        }
        else if(node && node->val < L) 
        {
            //delete left sub tree
            //then check right sub tree
            //Also need to delete current node and link right (if needed)
            //this can be done by simply setting current node to 
            //its right
            if(node->left == nullptr && node->right == nullptr)
            {
                std::cout << "deleting node 0" << std::endl;
                std::cout << "Address prior to freeing: " << node << std::endl;

                delete node;
                node = nullptr;
                std::cout << "Address after freeing: " << node << std::endl;
                return;
            }

            if(node->left)
            {
                delete node->left;
                node->left = nullptr;
            }
            if(node->right)
            {
                node = node->right;
            }
            std::cout << "done" << std::endl;
        }    

        std::cout << "end" << std::endl;
    }
};


int main(int argc, char const *argv[])
{
   /* code */
   binary_search_tree<int> my_tree;
   Solution<int> soln;

   my_tree.insert(1);
   my_tree.insert(0);
   my_tree.insert(2);

   soln.trimBST(my_tree.get_root(), 1, 2);


   return 0;
}

执行此代码时,我得到以下输出:

0x0
0x0
0x0
end
0x7fdeaec02af0
deleting node 0
Address prior to freeing: 0x7fdeaec02af0
Address after freeing: 0x0
0x7fdeaec02af0
0x7fdeaec02af0
end

在递归调用期间将删除指向值为0的节点的指针,并将其设置为nullptr。但是,当它从递归调用返回时(指针通过引用传递),指针仍指向与删除并设置为nullptr之前相同的内存地址。

我不知道为什么会这样。我唯一的猜测是我某处发生内存泄漏,导致我应该将delete应用于的指针出现问题。

1 个答案:

答案 0 :(得分:0)

首先,我想告诉您,您的节点结构只应有一个content和两个pointer自己,才能显示rightleft的孩子。 那么为了显示BST,您应该cout数据不是该指针

class node
{
    friend class BST;
public:
    node(int Content=0,node* R_child = NULL, node*L_child = NULL)
    {
        this->R_child = R_child;
        this->L_child = L_child;
        this->Content = Content;
    }

private:
    int Content;
    node*R_child;
    node*L_child;
    };

检查此代码中的节点类,可以使用模板而不是整数。 祝你好运