简体   繁体   中英

Deleting multiple nodes in a Binary Search Tree

I'm not quite sure how to remove Nodes in my binary search tree. I've been specified to remove any Student objects with a grade value of less than 50. This is my remove function

bool remove(BTNode<value_type>* cNode, value_type& data)
{
    if(cNode == NULL)
    {
        return false;
    }

    if(data.get_name() > cNode->get_data().get_name())
    {
        remove(cNode->get_right(), data);
    }
    else if(data.get_name() < cNode->get_data().get_name())
    {
        remove(cNode->get_left(), data);
    }
    else
    {
        if(cNode->is_leaf())
        {
            if(root->get_data().get_name() == data.get_name())
            {
                root = NULL;
            }
            else
            {
                if(cNode->is_right_child())
                {
                    cNode->get_parent()->set_right(NULL);
                }
                else
                {
                    cNode->get_parent()->set_right(NULL);
                }
            }
            delete cNode ;
            size--;
        }
        else if(cNode->has_one_child())
        {
            if(root->get_data().get_name() == data.get_name())
            {
                if(cNode->get_right()!= NULL)
                {
                    cNode->get_right()->set_parent(NULL);
                    root = cNode->get_right();
                }
                else
                {
                    cNode->get_left()->set_parent(NULL);
                    root = cNode->get_left();
                }
            }
            else if(cNode->get_right() != NULL)
            {
                cNode->get_right()->set_parent(cNode->get_parent());
                if(cNode->is_right_child())
                {
                    cNode->get_parent()->set_right(cNode->get_right());
                }
                else
                {
                    cNode->get_parent()->set_left(cNode->get_left());
                }
            }
            else
            {
                BTNode<value_type>* tempNode = find_min(cNode->get_right());
                value_type* tempStudent = new value_type (tempNode->get_data());
                remove(cNode->get_right(), tempNode->get_data());
                cNode->set_data(*tempStudent);
            }
            return true;
        }
        return false;
    }
}

And recursively calling it with

bool remove(value_type& data)
{
    return remove(root, data);
}

The student object I'm trying to remove is constructed like so

Student::Student(std::string init_name)
{
    name = init_name;
    grade = rand() % 101;
}

and in my main function I have

BSTree<Student>* student_tree = new BSTree<Student>;
std::string studentName[]={"Adam", "Cameron", "Jackson", "KiSoon", "Nicholas", "Adrian", "Chris", "Jacob", "Lance", "Ryan",
                           "Alexander", "Damian", "James", "Liam", "Sang", "Andrew", "David", "Jared", "Madison", "Shane", "Ashley", "Dillon",
                           "Jodi", "Magdalena", "Simon", "Benjamin", "Dylan", "Jonathan",  "Marcus", "Thomas", "Bradley", "Ethan", "Joshua", "Mark",
                           "Timothy", "Brobie", "Frederik", "Julius", "Melanie", "Trent", "Callan", "Hong", "Kelly", "Min", "Troy", "Callum", "Hugh", "Kenias", "Mitchell", "Zaanif"};

for (int i = 49; i > 0; i--)
{ 
    int j = rand() % (i+1);
    std::string tmp = studentName[j];
    studentName[j] = studentName[i];
    studentName[i] = tmp;
} 

for (int i = 0; i < 50; i++)
{
    Student student = Student(studentName[i]);
    student_tree->insert(student, i);
}

cout << student_tree->printInOrder() << endl;
//cout << "test" << endl;
cout << "HD's: " << student_tree->hdCount() << endl;
cout << "Average: " << student_tree->avg() << endl;
student_tree->remove();

I have no idea what to pass in as the parameter for remove. I assume it is the name of the students with a grade of less than 50, but I'm not sure on how to loop through and grab these names and put them into the function call.

Edit: In remove, should I be checking the name of the Node and the data passed in or the grade of the Node and data passed? ie if(data.get_name() > cNode->get_data().get_name()) or if(data.get_grade() > cNode->get_data().get_grade())

It looks like your function call and parameters are okay.

However, it looks like you are only choosing to traverse certain paths of the tree. If you want to remove all nodes that contain a grade of less than 50, you will have to iterate through the entire tree, like so: return remove(cNode->get_left(), data) || remove(cNode->get_right(), data);

You will then have the base case, which you already have correct: if(cNode == NULL) return false;

You will then check if the grade of cNode is less than 50. if so, remove it, and return true.

-I am assuming you have a student as well as their data/grade info in each node

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM