Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从二叉搜索树中删除节点时遇到困难_C++_Recursion_Binary Search Tree - Fatal编程技术网

C++ 从二叉搜索树中删除节点时遇到困难

C++ 从二叉搜索树中删除节点时遇到困难,c++,recursion,binary-search-tree,C++,Recursion,Binary Search Tree,我正在创建一个二元搜索树,它需要能够删除一个节点,如果该节点被正确删除,则返回true;如果该值在树中不存在,则返回false。我这样做是因为我需要删除多个数字,并且我想创建一个while循环来删除所有的数字。例如,一棵树具有以下整数:{79、83、147、71、95、49、15、191}。另一棵树有以下整数{26,79,144,88,147,200,90}。我的任务是找到树1中的所有元素,这些元素在树2中,并将它们从树1中删除(在本例中为79和147)。我想创建一个循环,通过树2中的所有数字运

我正在创建一个二元搜索树,它需要能够删除一个节点,如果该节点被正确删除,则返回true;如果该值在树中不存在,则返回false。我这样做是因为我需要删除多个数字,并且我想创建一个while循环来删除所有的数字。例如,一棵树具有以下整数:{79、83、147、71、95、49、15、191}。另一棵树有以下整数{26,79,144,88,147,200,90}。我的任务是找到树1中的所有元素,这些元素在树2中,并将它们从树1中删除(在本例中为79和147)。我想创建一个循环,通过树2中的所有数字运行,并从树1中搜索和删除。以下是我到目前为止关于remove node函数的内容(假设已经构建并填充了树):

节点h:

template<class ItemType>
class Node {
public:
    ItemType data;
    Node * left;
    Node * right;

    //Constructors / Destructors
    Node ();
    Node ( ItemType inData );
    ~Node ();
};

//--------------------------------------------------------------//
//--                Constructor / Destructor                  --//
//--------------------------------------------------------------//
/** Standard Constructor */
template<class ItemType>
Node<ItemType>::Node () {
    left = right = NULL;
}

/** Overload Constructor */
template<class ItemType>
Node<ItemType>::Node ( ItemType inData ) {
    data = inData;
    left = right = NULL;
}

/** Standard Destructor */
template<class ItemType>
Node<ItemType>::~Node () {
    right = left = NULL;
}
模板
类节点{
公众:
项目类型数据;
节点*左;
节点*右;
//构造函数/析构函数
节点();
节点(ItemType inData);
~Node();
};
//--------------------------------------------------------------//
//--构造函数/析构函数--//
//--------------------------------------------------------------//
/**标准构造器*/
模板
Node::Node(){
左=右=空;
}
/**重载构造函数*/
模板
节点::节点(ItemType inData){
数据=inData;
左=右=空;
}
/**标准析构函数*/
模板
节点::~节点(){
右=左=空;
}
从Source.cpp:

Tree2.postorder_print ();

int ridOf = 79;

if (Tree2.remove ( ridOf )) {
        Tree2.postorder_print ();
        cout << endl << "Number of Nodes: " << Tree2.get_num_of_nodes () << endl;
        cout << "Height:          " << Tree2.get_tree_height () << endl << endl;
    }
Tree2.postorder_print();
int-ridOf=79;
如果(Tree2.remove(ridOf)){
Tree2.postorder_print();
正确;
Node*tempLeft=新节点;
tempLeft=inRoot->left;
inRoot=nullNode;
inRoot=温度;
temp->left=tempLeft;
临时->右侧=临时右侧;
返回true;
}
//如果inRoot有一个子项
否则{
//如果inRoot离开了孩子
如果(inRoot->right==NULL){
节点*temp=新节点;
温度=根->左;
inRoot=nullNode;
inRoot=温度;
返回true;
}
//如果inRoot有正确的子对象
否则{
节点*temp=新节点;
temp=inRoot->right;
inRoot=nullNode;
inRoot=温度;
返回true;
}
}
}
//如果不是,则查看包含数据的节点的toRemove是否小于inRoot,并执行递归操作
else if(删除data){
删除辅助对象(在根->左,删除);
}//如果结束(删除data)
//查看toRemove是否大于inRoot并执行递归操作
否则如果(删除>根目录->数据){
删除辅助对象(在根->右侧,删除);
}//别有用心
//如果找不到数据,则返回false
否则返回false;
}
我的一些结果是不同的,都是错误的。一个结果是无限循环不断地反复打印树。另一个结果是它执行了删除操作,看起来很成功,但如果查看两个打印输出,它们是相同的,并且节点未被删除(如果返回false,则不应再次打印,但确实如此)。然后,第三个结果发生在第二次打印预订单期间。它会中断并在空节点上停止,但左右两侧的数据都显示“无法读取内存”。我做错了什么?我想不出来。我的所有其他树函数(包括预订单打印),直到我尝试删除一个节点


只是想澄清一点,我的remove\u helper函数有问题。因此,我可以继续从Tree1中删除Tree2中存在的节点

你要做的是在两棵树之间倒交叉。可以通过创建一个带有两个参数的函数来实现这一点。一个参数是要从中删除内容的树(tree1),另一个参数是要检查的树(tree2)


然后在函数中使用递归检查树2。对于您取出的每个元素,您使用该元素来搜索它是否存在于树1中(在这种情况下,还可以删除它)。然后继续在tree1中搜索tree2中的每个节点,直到遍历tree2中的每个元素。

remove\u helper
正在尝试更改
inRoot
参数的值。但是,
inRoot
是按值传递的,因此在函数中所做的任何更改都不会反映在调用函数中

remove\u helper
函数更改为通过引用获取
inRoot
,然后它将能够修改调用函数中使用的参数值:

template<class ItemType>
bool BTree<ItemType>::remove_helper (Node<ItemType> * &inRoot, ItemType toRemove) {
您正在分配一些内存并在
tempRight
中指向它,然后立即将
tempRight
设置为其他内容。这是内存泄漏,是不必要的-您不需要为每个指针分配内存。 将其更改为:

 Node<ItemType> * tempRight = inRoot->right;
Node*tempRight=inRoot->right;

好的,@TheDark提供了大量帮助,这是我的删除辅助功能:

template<class ItemType>
bool BTree<ItemType>::remove_helper (Node<ItemType> * &inRoot, ItemType toRemove) {
    //if this is the node with the data
    if (inRoot->data == toRemove) {
        //if inRoot has No Children
        if (inRoot->left == NULL && inRoot->right == NULL ) {
            inRoot = NULL;
            std::cout << "one" << std::endl;
            return true;
        }
        //if inRoot has 2 Children
        else if (inRoot->left != NULL && inRoot->right != NULL) {
            inRoot->data = return_max_value ( inRoot->left )->data;
            remove_helper (inRoot->left,inRoot->data);
            std::cout << "two" << std::endl;
            return true;
        }
        //if inRoot has 1 child
        else {
            std::cout << "zero" << std::endl;
            //if inRoot has left child
            if (inRoot->right == NULL) {
                Node<ItemType> * temp = new Node < ItemType >;
                temp = inRoot->left;
                inRoot = NULL;
                inRoot = temp;
                return true;
            }
            //if inRoot has right child
            else {
                Node<ItemType> * temp = new Node < ItemType >;
                temp = inRoot->right;
                inRoot = NULL;
                inRoot = temp;
                return true;
            }
        }
    }
    //If not the node with the data See if toRemove is less than inRoot and perform recursive action
    else if ( toRemove < inRoot->data ) {
        remove_helper ( inRoot->left, toRemove );
    } //end if (toRemove < inRoot->data) 
    //See if toRemove is greater than inRoot and perform recursive action
    else if ( toRemove > inRoot->data)  {
        remove_helper ( inRoot->right, toRemove );
    }// end of else 

    //return false if data cannot be found
    else return false;
}
模板
boolbtree::remove\u helper(Node*&inRoot,ItemType-toRemove){
//如果这是包含数据的节点
如果(inRoot->data==toRemove){
//如果inRoot没有孩子
如果(inRoot->left==NULL&&inRoot->right==NULL){
inRoot=NULL;
std::cout right!=NULL){
inRoot->data=返回最大值(inRoot->left)->数据;
删除辅助对象(inRoot->left,inRoot->data);
std::cout;
temp=inRoot->right;
inRoot=NULL;
inRoot=温度;
返回true;
}
}
}
//如果不是,则查看包含数据的节点的toRemove是否小于inRoot,并执行递归操作
否则如果(删除数据
 Node<ItemType> * tempRight = new Node < ItemType >;
 tempRight = inRoot->right;
 Node<ItemType> * tempRight = inRoot->right;
template<class ItemType>
bool BTree<ItemType>::remove_helper (Node<ItemType> * &inRoot, ItemType toRemove) {
    //if this is the node with the data
    if (inRoot->data == toRemove) {
        //if inRoot has No Children
        if (inRoot->left == NULL && inRoot->right == NULL ) {
            inRoot = NULL;
            std::cout << "one" << std::endl;
            return true;
        }
        //if inRoot has 2 Children
        else if (inRoot->left != NULL && inRoot->right != NULL) {
            inRoot->data = return_max_value ( inRoot->left )->data;
            remove_helper (inRoot->left,inRoot->data);
            std::cout << "two" << std::endl;
            return true;
        }
        //if inRoot has 1 child
        else {
            std::cout << "zero" << std::endl;
            //if inRoot has left child
            if (inRoot->right == NULL) {
                Node<ItemType> * temp = new Node < ItemType >;
                temp = inRoot->left;
                inRoot = NULL;
                inRoot = temp;
                return true;
            }
            //if inRoot has right child
            else {
                Node<ItemType> * temp = new Node < ItemType >;
                temp = inRoot->right;
                inRoot = NULL;
                inRoot = temp;
                return true;
            }
        }
    }
    //If not the node with the data See if toRemove is less than inRoot and perform recursive action
    else if ( toRemove < inRoot->data ) {
        remove_helper ( inRoot->left, toRemove );
    } //end if (toRemove < inRoot->data) 
    //See if toRemove is greater than inRoot and perform recursive action
    else if ( toRemove > inRoot->data)  {
        remove_helper ( inRoot->right, toRemove );
    }// end of else 

    //return false if data cannot be found
    else return false;
}