簡體   English   中英

節點未從二叉搜索樹中刪除 C++

[英]Node Not being Deleted from Binary Search Tree C++

我一直試圖讓 25 從樹中刪除,但我無法刪除它。 我試過調試和創建斷點和一切,沒有任何效果。 我已經一年多沒有像這樣編碼了,事實證明這是非常令人生畏的。

請幫忙!

![輸出] ( https://i.gyazo.com/8e953ebe14d9d33a2a0ffa233ccfacb1.png )

#ifndef BSTREE_H
#define BSTREE_H
#include <iostream>
#include <iomanip>
using namespace std;

// class must be templated
template <class DataType>
class BSTree
{
private:
// You may NOT add any data members
struct node;
typedef node* nodePtr;

struct node
{
    DataType element;
    nodePtr right;
    nodePtr left;
};
int count;
nodePtr root;

// You may add any private member functions here
bool isEmpty() // helper funtion for determining if the tree is empty
{
    return root == NULL;
}

void inOrderPrint(nodePtr x, ostream& out)
{
    if (root != NULL)
    {
        inOrderPrint(x->left, out);
        out << x->element << " ";
        inOrderPrint(x->right, out);
    }
}

void preOrderPrint(nodePtr x, ostream& out)
{
    if (root != NULL)
    {
        out << x->element << " ";
        preOrderPrint(x->left, out);
        preOrderPrint(x->right, out);
    }
}

bool search(DataType x) // helper function to check if item is in tree already
{
    bool found = false;
    if (isEmpty())
    {
        cout << "Nothing in the Tree!" << std::endl;
        return false;
    }
    nodePtr current;
    nodePtr parent;
    current = root;
    parent = NULL;
    while (current != NULL)
    {
        if (current->element == x)
        {
            found = true;
            break;
        }
        else
        {
            //parent = current;
            if (x > current->element)
            {
                current = current->right;
            }
            else
            {
                current = current->left;
            }
        }
    }
    if (!found)
    {
        found = false;
    }
    else
    {
        found = true;
    }
    return found;

}

/*
nodePtr findNode(nodePtr x)
{
    bool found = false;
    if (isEmpty())
    {
        cout << "Nothing in the Tree!" << std::endl;
        return;
    }
    nodePtr current;
    nodePtr parent;
    current = root;
    parent = NULL;
    while (current != NULL)
    {
        if (current->element == x->element)
        {
            found = true;
            return x;
            break;
        }
        else
        {
            parent = current;
            if (x->element > current->element)
            {
                current = current->right;
            }
            else
            {
                current = current->left;
            }
        }
    }
    if (!found)
    {
        found = false;
        return;
    }
    else
    {
        found = true;
    }
    return x;

}
*/

void destroyTree(nodePtr x)
{
    if (x != NULL)
    {
        destroyTree(x->left);
        destroyTree(x->right);
        delete x;
    }
}

// This method is given – it is called by printTree
void printTreeHelper(int depth, nodePtr cur) const
{
    const int spacing = 4;
    if (cur != NULL)
    {
        if (depth == 0)
            cout << cur->element;
        else
            cout << setw(spacing * depth) << " " << cur->element;
        cout << endl;
        printTreeHelper(depth + 1, cur->right);
        printTreeHelper(depth + 1, cur->left);
    }
    else
        cout << setw(spacing * depth) << " " << "****" << endl;

}

void copyTreeHelper(nodePtr x)
{
    if (x != NULL)
    {
        insert(x->element);
        copyTreeHelper(x->left);
        copyTreeHelper(x->right);
    }
}

nodePtr minNodeFinder(nodePtr min)
{
    nodePtr curr = min;
    while ((curr != NULL) && (curr->left != NULL))
    {
        curr = curr->left;
    }
    return curr;
}

public:
// Default constructor
BSTree()
{
    root = NULL;
}

// Copy constructor
BSTree(const BSTree<DataType>& copyTree)
{
    root = NULL;
    copyTreeHelper(copyTree.root);
}

// Equal overload
const BSTree& operator =(const BSTree& rhs)
{
    if (this == &rhs)
    {
        return *this;
    }
    else
    {
        copyTreeHelper(rhs.root);
        deleteTree();
        return *this;
    }
}

// Destructor
~BSTree()
{
    deleteTree();
}

// Inserts element into the tree
// If value is already in the tree do NOt add it
// a second time
void insert(DataType x)
{
    if (search(x))
    {
        cout << "item already in tree" << std::endl;

    }
    else
    {
        nodePtr temp = new node();
        nodePtr parent;
        temp->element = x;
        temp->left = NULL;
        temp->right = NULL;
        parent = NULL;
        if (isEmpty())
        {
            root = temp;
        }
        else
        {
            nodePtr current;
            current = root;
            while (current)
            {
                parent = current;
                if (temp->element > current->element)
                {
                    current = current->right;
                }
                else
                {
                    current = current->left;
                }
            }
            if (temp->element < parent->element)
            {
                parent->left = temp;
            }
            else
            {
                parent->right = temp;
            }
        }
    }
}

//Print the tree as a tree
// This (and its helper function) is given to you
// See sample output and understand how the tree is displayed
// because it can help when testing the code
bool printTree() const
{
    if (root == NULL)
        return false;
    else
    {
        printTreeHelper(0, root);
        return true;
    }
}

// Prints tree in order to the screen
// call printInOrder with  cout passed in
// This function is done for you
void printInOrder()
{
    printInOrder(cout);
}

// Prints the tree in order to
// the ostream passed into it
void printInOrder(ostream& out)
{
    inOrderPrint(root, out);
    out << std::endl;
}

// Prints tree in preorder to the screen
// call printPreOrder with  cout passed in
// This function is done for you
void printPreOrder()
{
    printPreOrder(cout);
}
// Prints the tree in preorder to
// the ostream passed into it
void printPreOrder(ostream& out)
{
    preOrderPrint(root, out);
    out << std::endl;
}

// Deletes the item passed in from the tree
// It returns a true if it finds it and deletes it, otherwise
// It returns a false
bool  deleteNode(DataType x)
{
    
    if (!search(x))
    {
        cout << "Item not found" << std::endl;
        return false;
    }
    nodePtr current;
    nodePtr parent;
    current = root;
    parent = NULL;
    //Node is a single node with one child
    if((current->left == NULL && current->right != NULL) ||
       (current->left != NULL && current->right == NULL))
    {
        if(current->left == NULL && current->right != NULL) // right child is present
        {
            if(parent->left == current)
            {
                parent->left = current->right;
                delete current;
            }
            else
            {
                parent->right = current->right;
                delete current;
            }
        }
        else // left child is present
        {
            if (parent->left == current)
            {
                parent->left = current->left;
                delete current;
            }
            else
            {
                parent->right = current->left;
                delete current;
            }
        }
        return true;
    }
    // node is a leaf node
    if (current->left == NULL && current->right == NULL)
    {
        if(parent == NULL)
        {
            delete current;
        }
        else
        {
            if(parent->left == current)
            {
                parent->left = NULL;
            }
            else
            {
                parent->right = NULL;
            }
            delete current;
            return true;
        }
    }
    // node has two children i.e parent node
    if (current->left != NULL && current->right != NULL)
    {
        nodePtr checker;
        checker = current->right;
        if ((checker->left == NULL) && (current->right == NULL))
        {
            current = checker;
            delete current;
            current->right = NULL;
        }
        else // right child has children
        {
            //nodes right child has a left child
            if ((current->right)->left != NULL)
            {
                nodePtr left_current;
                nodePtr left_current_parent;
                left_current_parent = current->right;
                left_current = (current->right)->left;
                while (left_current->left != NULL)
                {
                    left_current_parent = left_current;
                    left_current = left_current->left;
                }
                current->element = left_current->element;
                delete left_current;
                left_current_parent->left = NULL;
            }
            else
            {
                nodePtr temp;
                temp = current->right;
                current->element = temp->element;
                current->right = temp->right;
                delete temp;
            }
        }
    }
    return true;
}

// Deletes the item passed in from the tree
// It also passes back the item to the calling function
// It returns a true if it finds it and deletes it, otherwise
// It returns a false
bool  deleteNodePassBackData(DataType x, DataType& temp)
{
    if (search(x))
    {
        nodePtr itemToDelete = findNode(x);
        temp = itemToDelete->element;
        deleteNode(x);
        return true;
    }
    else
    {
        return false;
    }
}

// Deletes the whole tree
void deleteTree()
{
    destroyTree(root);
}
};

#endif


     BSTree<int> t1;
  t1.insert(50);
  t1.insert(75);
  t1.insert(25);
  t1.insert(22);
  t1.insert(5);
  t1.insert(85);
  t1.insert(95);
  t1.insert(82);
  t1.insert(76);
  t1.printTree();

  BSTree<int> t2(t1);
  t2.deleteNode(25);
  t2.deleteNode(75);
  t2.deleteNode(50);
  
  cout << "After copy constructor and deletes" << endl;
  cout << "T1" << endl;
  t1.printTree();
  cout << "T2" << endl;
  t2.printTree();

首先,您應該始終發布完整代碼供其他人調試。 如果我不能運行你的代碼,我到底怎么調試它呢?

但除此之外,代碼中的deleteNode(DataType x)存在嚴重問題。
current從不遍歷樹。
deleteNode() function 如果項目存在於樹中,將始終刪除樹的根。

您應該像在deleteNode() function 中的search() function 中那樣遍歷樹。

順便問一下,以下代碼在search()中的意義何在?

if (!found)
{
    found = false;
}
else
{
    found = true;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM