如何在c ++中修复分段错误11

时间:2015-04-19 17:11:54

标签: c++ segmentation-fault binary-tree

我目前正在用c ++编写一个二叉树项目,它给了我一些我很难理解的错误。有问题的错误是分段错误,我不知道如何修复。下面是一个代码,其中包含编写所有函数的文件。特别是给我一个问题的函数是最后一个 - print_pre_order_private函数。

#include <iostream>
#include <cstdlib>

#include "BT.h"

using namespace std;

BT::BT()
{
    root = NULL;  //makes sure pointer isn't pointing at anything
}

BT::node* BT::create_leaf(int key)
{
    node* n = new node;
    n->key = key;
    n->left = NULL;
    n->right = NULL;

    return n;
}

void BT::add_leaf(int key)
{
    add_leaf_private(key, root);
} 

void BT::add_leaf_private(int key, node* Ptr)
{
    if(root == NULL)
    {
        root = create_leaf(key);
    }

    else if(key < Ptr->key)
    {
        if(Ptr->left != NULL)
        {
             add_leaf_private(key, Ptr->left);
        }
        else
        {
            Ptr->left = create_leaf(key);
        }
    }

    else if(key > Ptr->key)
    {
        if(Ptr->right != NULL)
        {
             add_leaf_private(key, Ptr->right);
        }
        else
        {
            Ptr->right = create_leaf(key);
        }
    }
    else
    {
        cout << "The key " << key << " has already been added to the    tree\n";
    }
}

void BT::print_in_order()
{
    print_in_order_private(root);
}

void BT::print_in_order_private(node* Ptr)
{
    if(root != NULL)
    {
        if(Ptr->left != NULL)
        {
            print_in_order_private(Ptr->left);
        } 
        cout << Ptr->key << " ";
        if(Ptr->right != NULL)
        {
            print_in_order_private(Ptr->right);
        }
    } 
    else
    {
        cout << "The tree is empty\n";
    }
}

BT::node* BT::return_node(int key)
{
    return return_node_private(key, root);
}

BT::node* BT::return_node_private(int key, node* Ptr)
{
    if(Ptr != NULL)
    {
        if(Ptr->key == key)
        {
            return Ptr;
        }

        else
        {
            if(key < Ptr->key)
            {
                return return_node_private(key, Ptr->left);
            }

            else
            {
                return return_node_private(key, Ptr->right);
            }
        }
    }
    else
    {
        return NULL;
    }
}

int BT::return_root_key()
{
    if(root != NULL)
    {
        return root->key;
    }
    else
    {
        return -1;
    }
}

void BT::print_children(int key)
{
   node* Ptr = return_node(key);

    if(Ptr != NULL)
    {
        cout << "Parent Node = " << Ptr->key << endl;

        Ptr->left == NULL ?
        cout << "Left child = NULL\n":
        cout << "Left child = " << Ptr->left->key << endl;

        Ptr->right == NULL ?
        cout << "Right child = NULL\n":
        cout << "Right child = " << Ptr->right->key << endl;
     }
     else
     {
        cout << "Key " << key << " is not in the tree\n";
     }

 }

int BT::find_smallest()
{
    return find_smallest_private(root);
}

int BT::find_smallest_private(node* Ptr)
{
    if(root == NULL)
    {
        cout << "The tree is empty\n";
        return -1;
    }
    else
    {
        if(Ptr->left != NULL)
        {
            return find_smallest_private(Ptr->left);
        }
        else
        {
            return Ptr->key;
        }
    }
}


void BT::remove_node(int key)
{
     remove_node_private(key, root);
}  

void BT::remove_node_private(int key, node* parent)
{
    if(root != NULL)
   {
    if(root->key == key)
    {
        remove_root_match();
    }
    else
    {
        if(key < parent->key && parent->left != NULL)
        {
             parent->left->key == key ?
             remove_match(parent, parent->left, true) :
             remove_node_private(key, parent->left);
        }   
        else if(key < parent->key && parent->right != NULL)
        {
             parent->right->key == key ?
             remove_match(parent, parent->right, true) :
             remove_node_private(key, parent->right);
        }
        else
        {
            cout << "The key " << key << " was not found in the tree\n";
        }
    }
}
else
{
    cout << "The tree is empty\n";
}
}

void BT::remove_root_match()
{
    if(root != NULL)
    {
        node* delPtr = root;
        int root_key = root->key;
        int smallest_right_subtree;

        //case 0 - 0 children
        if(root->left == NULL && root->right == NULL)
        {
            root = NULL;
            delete delPtr;
        }

        //case 1 - 1 child
        else if(root->left == NULL && root->right != NULL)
        {
            root = root->right;
            delPtr->right = NULL;
            delete delPtr;
            cout << "The root node with key " << root_key << " was deleted. " 
            << " The new root contains key " << root->key << endl;

        }
        else if(root->right == NULL && root->left != NULL)
        {
            root = root->left;
            delPtr->left = NULL;
            delete delPtr;
            cout << "The root node with key " << root_key << " was deleted. " 
            << " The new root contains key " << root->key << endl;

        }
        //case 2 - 2 children
        else
        {
            smallest_right_subtree = find_smallest_private(root->right);
            remove_node_private(smallest_right_subtree, root);
            root->key = smallest_right_subtree;
            cout << "The rout key containing key " << root_key
            << " was overwritten with key " << root->key << endl;
        }
   }
    else
    {
        cout << "Cannot remove root. Tree is empty\n";
    }
}

void BT::remove_match(node* parent, node* match, bool left)
{
    if(root != NULL)
    {
        node* delPtr;
        int match_key = match->key;
        int smallest_right_subtree;

        //case 0 - 0 children
        if(match->left == NULL && match->right == NULL)
        {
            delPtr = match;
            left == true ? parent->left = NULL : parent->right = NULL;
            delete delPtr;
            cout << "The node containing key " << match_key << " was removed\n";
        }

        //case 1 - 1 child
        else if(match->left == NULL && match->right != NULL)
        {
            left == true ? parent->left = match->left : parent->right = match->right;
            match->left = NULL;
            delPtr = match;
            delete delPtr;
            cout << "The node containing key " << match_key << " was removed\n";
        }
        //case 2 - 2 children
        else
        {
            smallest_right_subtree = find_smallest_private(match->right);
            remove_node_private(smallest_right_subtree, match);
            match->key = smallest_right_subtree;
        }
    }
    else 
    {
        cout << "Cannot remove match. The tree is empty";
    }
}

void print_pre_order()
{
    print_pre_order_private(root);
}
void print_pre_order_private(node* Ptr)
{
    if(root != NULL)
    {
        cout << Ptr->key << " ";
        print_pre_order_private(Ptr->left);
        print_pre_order_private(Ptr->right);
    }
}

非常感谢任何帮助解决这种情况。提前致谢。 :)

1 个答案:

答案 0 :(得分:0)

在print_pre_order_private(node * Ptr)函数中。不应该是&#34; if(Ptr!= NULL)&#34;而不是&#34; if(root!= NULL)&#34; ?。我认为有崩溃。

因为你设计了&#34; print_pre_order_private()&#34;作为一个递归函数,你应该检查&#34; Ptr&#34;的有效性。而不是总是检查&#34; root&#34;的有效性,因为根据你的输入,孩子的左/右/两者在树的最底部可能是NULL。