Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.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++_Tree_Runtime_Binary Tree - Fatal编程技术网

C++ 原始二叉树删除与复制问题(改进的解释)

C++ 原始二叉树删除与复制问题(改进的解释),c++,tree,runtime,binary-tree,C++,Tree,Runtime,Binary Tree,我已经创建了原始二进制树。在此树中,插入与BST不同,它类似于: 如果树为空,则添加值并使其成为根。(假设30) 若树不是空的,则输入父值(30)并向其左子树添加新值(20) 若左子树不为空,则在右子树中插入值(20) 对于下一次插入,再次获取父值以确定要添加值的位置。 &以此类推 它工作正常,除非我试图删除一个有两个子节点的节点。我用来删除的方法是deleteWithCopy 正如我的导师所说,deletewithcopy是: 1.查找要删除的节点(临时)的父节点。 2.如果temp(要删除的

我已经创建了原始二进制树。在此树中,插入与BST不同,它类似于:

  • 如果树为空,则添加值并使其成为根。(假设30)
  • 若树不是空的,则输入父值(30)并向其左子树添加新值(20)
  • 若左子树不为空,则在右子树中插入值(20)
  • 对于下一次插入,再次获取父值以确定要添加值的位置。 &以此类推
  • 它工作正常,除非我试图删除一个有两个子节点的节点。我用来删除的方法是deleteWithCopy

    正如我的导师所说,deletewithcopy是: 1.查找要删除的节点(临时)的父节点。 2.如果temp(要删除的节点)是“父”的正确子级,则查找temp的直接继承者 3.如果temp(要删除的节点)是“父”的左子级,则查找temp的直接前级 4.将临时值与其前任/继任者交换 5.删除临时文件(现在是树的叶子)

    现在如何找到继任者和前任。

    继任者=节点的逻辑继任者是其左子树中最右边的子节点

    前置节点=节点的逻辑前置节点是其右子树中最左边的子节点

    根据算法,我创建了函数,但删除后,当我遍历(或打印)树时,它显示运行时错误, binarytree.exe中0x008B5853处的未处理异常:0xC0000005:访问冲突读取位置0xFEEEFEEE。 在VisualC++中用0xFIEEEFEE标记空闲内存是错误的。 我已经一次又一次地试运行了这件事&再一次,我尝试访问的内存中没有超出范围的内容,我已经修复了所有未解决的问题,但仍然:(

    函数如下:

    void BinaryTree<mytype>::deletewithTwoChild(BTNode<mytype> *temp)
    {
        BTNode<mytype> *father = findfather(temp, root);    //found address of father of temp node & stored it in pointer
        BTNode<mytype> *leaf = temp;    //created a copy of temp node
    
        /////CASE 1 (for predecessor)
    if(temp==root || father->left==temp)    //if temp is left child of its father then
    {
        leaf = leaf->left;  //move leaf 1 time left
        while(leaf->right!=0 )  //until leaf reaches the right most node of left subtree
        {
            leaf = leaf->right; //move leaf 1 time to right
        }
        //swapping values
        mytype var = leaf->key_value;   //created a template variable to store leaf's key
        leaf->key_value = temp->key_value;  //assigning temp's key to leaf
        temp->key_value = var;  //assigning leaf's key to temp
        if(leaf->right!=0)  //if leaf has right child then call deletewithOneChild function
        {
            deletewithOneChild(leaf);   //call to respective function
        }
        else if(leaf->left==0 && leaf->right==0) //if leaf has no children then
        {
            deleteWithNoChild(leaf);    //call to respective function
        }
    }
    /////CASE 2 (for successor)
    else if(father->right==temp)    //if temp is right child of its father, then
    {
        leaf = leaf->right; //move leaf 1 time right
        while(leaf->left!=0)    //until leaf reaches the last node of tree which has no child
        {
            leaf = leaf->left;  //move leaf 1 time to left
        }
        //swapping values
        mytype var = leaf->key_value;   //created a template variable to store leaf's key
        leaf->key_value = temp->key_value;  //assigning temp's key to leaf
        temp->key_value = var;  //assigning leaf's key to temp
        if(leaf->right!=0)  //if leaf has right child then call deletewithOneChild function
        {
            deletewithOneChild(leaf);   //call to respective function
        }
        else if(leaf->left==0 && leaf->right==0) //if leaf has no children then
        {
            deleteWithNoChild(leaf);    //call to respective function
        }
    }
    

    当运行时错误弹出时,我试图删除节点80、60、120、140。Plz帮助:((我还需要指南)如何处理树iff 30被删除。

    正如我所知,后继和前置的定义是不同的

    后继者:右子树的最小节点,即右子树的最左侧节点。 前置:左子树的最大节点,即左子树的最右节点

    回到问题1。在案例1中交换值后,我注意到了
    if else
    的情况。因为在案例1中,您找到了子树最右边的节点,
    叶->右
    始终为
    叶->左
    可能不是
    。因此,无法调用任何删除函数在交换值后,在case中会出现异常。这将导致错误的BST问题,甚至更糟的是,程序崩溃。因此,case中的
    if-else
    条件为:

    // leaf->right always be null, only need to verify leaf->left.
    if (leaf->left != 0)
    {
        deleteWithOneNode(leaf);
    }
    else 
    {
        deleteWithNoChild(leaf);
    }
    
    void BinaryTree<myType>::delete(BTNode<myType>* node, BTNode<myType>* parent)
    {
        if (node->right) // find successor first
        {
            BTNode* ptrParent = node;
            BTNode* ptr = node->right;
            while (ptr->left)
            {
                ptrParnet = ptr;
                ptr = ptr->left;
            }
    
            // Since the ptr will be delete, we only assign the value of ptr to the value node
            node->key_value = ptr->key_value;
    
            if (node == ptrParent)
            {
                ptrParnet->right = ptr->right;
            }
            else
            {
                ptrParent->left = ptr->right;
            }
            delete ptr;            
        }
        else if (node->left) // find predecessor
        {
            BTNode* ptrParent = node;
            BTNode* ptr = node->left;
            while (ptr->right)
            {
                ptrParent = ptr;
                ptr = ptr->right;
            }
    
            // Since the ptr will be delete, we only assign the value of ptr to the value node
            node->key_value = ptr->key_value;
    
            if (node == ptrParent)
            {
                ptrParent->left = ptr->left;
            }
            else
            {
                ptrParent->right = ptr->left;
            }
            delete ptr; 
        }
        else
        {
            if (node->key_value > parent->key_value)
            {
                parent->right = NULL;
            }
            else
            {
                parent->left = NULL;
            }
            delete node;
        }
    }
    
    问题2。据我所知,BST中删除一个节点没有选择前置节点或后续节点的规则,删除节点的父(父)节点仅在交换整个节点时使用,而不是仅交换节点的值。因此,我的删除功能是:

    // leaf->right always be null, only need to verify leaf->left.
    if (leaf->left != 0)
    {
        deleteWithOneNode(leaf);
    }
    else 
    {
        deleteWithNoChild(leaf);
    }
    
    void BinaryTree<myType>::delete(BTNode<myType>* node, BTNode<myType>* parent)
    {
        if (node->right) // find successor first
        {
            BTNode* ptrParent = node;
            BTNode* ptr = node->right;
            while (ptr->left)
            {
                ptrParnet = ptr;
                ptr = ptr->left;
            }
    
            // Since the ptr will be delete, we only assign the value of ptr to the value node
            node->key_value = ptr->key_value;
    
            if (node == ptrParent)
            {
                ptrParnet->right = ptr->right;
            }
            else
            {
                ptrParent->left = ptr->right;
            }
            delete ptr;            
        }
        else if (node->left) // find predecessor
        {
            BTNode* ptrParent = node;
            BTNode* ptr = node->left;
            while (ptr->right)
            {
                ptrParent = ptr;
                ptr = ptr->right;
            }
    
            // Since the ptr will be delete, we only assign the value of ptr to the value node
            node->key_value = ptr->key_value;
    
            if (node == ptrParent)
            {
                ptrParent->left = ptr->left;
            }
            else
            {
                ptrParent->right = ptr->left;
            }
            delete ptr; 
        }
        else
        {
            if (node->key_value > parent->key_value)
            {
                parent->right = NULL;
            }
            else
            {
                parent->left = NULL;
            }
            delete node;
        }
    }
    

    在调试器中运行该程序。它将告诉您崩溃发生的位置,向您显示函数调用堆栈,让您看到崩溃是如何发生的,并让您检查变量以帮助您理解崩溃的原因。@JoachimPileborg I have,&它在访问临时节点(其值在交换后被删除)时显示错误。