【问题标题】:Find parent node function for binary tree查找二叉树的父节点函数
【发布时间】:2017-10-20 10:34:01
【问题描述】:

是否可以编写一个函数来返回给定节点的二叉树的父节点?

BinaryTree *search_val(BinaryTree *bt, int val)
{
    //temp pointer 
    BinaryTree* temp = NULL;
    if(!bt->isEmpty())
    {
        //check if root is equal to value and return root if true
        if(bt->getData() == val)
        {
            return bt;
        }
        else
        {
            //search left side
            temp = search_val(bt->left(), val);
            //if not found in left, search right
            if (temp == NULL)
            {
                temp = search_val(bt->right(), val);
            }
            return temp;
        }
        return NULL;
    }
    return NULL;
 }

我现在只有这个搜索功能。我实际上是从这里得到的。所以我试图将其转换为搜索节点的父节点。参数将是根节点和我们想要的父节点。这甚至可能吗? 我只需要一些提示即可开始,然后我将发布我的代码。创建此函数的目的是因为我有一个几乎可以完美运行的删除叶节点函数....唯一的问题是,当我在删除后打印所有节点时,仍会出现本应删除的节点。我确定这是因为父节点在 main.js 中仍然链接到它。这是我的删除叶节点功能:

void delete_leaf_node(BinaryTree *bt, int val)
{
    BinaryTree *temp;
    temp = search_val(bt, val);
    //If node does not exist in the tree, inform the user
    if(temp == NULL)
    {
        cout << "\n   " << val << " was not found in the tree" << endl; 
    }
    //Check if node is a leaf
    else if(temp->isLeaf())
    {
        delete temp;
        cout << "\n   Leaf " << temp->getData() << " deleted" << endl;
    }
    //Inform user that node is not a leaf
    else 
        cout << "\n   " << temp->getData() << " is not a Leaf" << endl; 
    //Display using In Order Traversal to see that the node was actually deleted    
    cout << "\n   In Order Traversal after deleting: " << endl << "\n   ";
    inOrderTraverse(bt);
    cout << endl;
} 

我希望我对某人有意义...对不起,我试图缩短问题但不能。

BinaryTree.h 文件:

using namespace std;

//BinaryTree class
class BinaryTree{
    public:
        BinaryTree();
        bool isEmpty();
        bool isLeaf();
        int getData();
        void insert(const int &DATA);
        BinaryTree *left();
        BinaryTree *right();
        void makeLeft(BinaryTree *bt);
        void makeRight(BinaryTree *bt);
    private:
        bool nullTree;
        int treeData;
        BinaryTree *leftTree;
        BinaryTree *rightTree;
};

BinaryTree.cpp 文件:

#include <iostream>
#include "BinaryTree.h"

using namespace std;

//constructor
BinaryTree::BinaryTree()
{
    nullTree = true;
    leftTree = NULL;
    rightTree = NULL;
}

/*
  is_empty function for BinaryTree class. Does not take any parameters. 
  Returns true if tree is empty and false otherwise.
*/
bool BinaryTree::isEmpty()
{
    return nullTree;
}

/*
  is_leaf function for BinaryTree class. Does not take any parameters. 
  Returns true if node has no children and false otherwise.
*/
bool BinaryTree::isLeaf()
{
    return ((this->leftTree->treeData == 0) && (this->rightTree->treeData == 0));
}

/*
  getData function for BinaryTree class. Does not take any parameters. 
  Returns treeData value.
*/
int BinaryTree::getData()
{
    if(!isEmpty());
    return treeData;
}

/*
  insert function for BinaryTree class. Takes one parameter, passed by
  reference. Returns true if node has no children and false otherwise.
*/
void BinaryTree::insert(const int &DATA)
{
    //create empty children and insert DATA
    treeData = DATA;
    if(nullTree) 
    {
        nullTree = false;
        leftTree = new BinaryTree;
        rightTree = new BinaryTree;
    }
}

/*
  left function for BinaryTree class. It points to the left node.
  Does not take any parameters. Returns left node.
*/
BinaryTree *BinaryTree::left()
{
    if(!isEmpty());
    return leftTree;
}

/*
  right function for BinaryTree class. It points to the right node.
  Does not take any parameters. Returns right node.
*/
BinaryTree *BinaryTree::right()
{
    if(!isEmpty());
    return rightTree;
}

/*
  makeLeft function for BinaryTree class. Takes a pointer to a tree node as a parameter. 
  makes the parameter the left child of a node. Does not return any value
*/
void BinaryTree::makeLeft(BinaryTree *bt)
{
    if(!isEmpty());
    leftTree = bt;
}

/*
  makeRight function for BinaryTree class. Takes a pointer to a tree node as a parameter. 
  makes the parameter the right child of a node. Does not return any value
*/
void BinaryTree::makeRight(BinaryTree *bt)
{
    if (!isEmpty());
    rightTree = bt;
}

谢谢

【问题讨论】:

    标签: c++ tree


    【解决方案1】:

    这取决于您的 BinaryTree 实现。据我所知,如果您不将每个节点内的引用保存到其父级,则删除时无法直接访问它

    编辑

    你可以修改你的 BinaryTree 类:

    class BinaryTree{
        public:
            BinaryTree();
            bool isEmpty();
            bool isLeaf();
            int getData();
            void insert(const int &DATA);
            BinaryTree *left();
            BinaryTree *right();
            void makeLeft(BinaryTree *bt);
            void makeRight(BinaryTree *bt);
    
            void setParent(BinaryTree *parent);
            BinaryTree* getParent();
        private:
            bool nullTree;
            int treeData;
            BinaryTree *leftTree;
            BinaryTree *rightTree;
    
            BinaryTree* parent;
    };
    

    然后在你的.cpp:

    BinaryTree::BinaryTree()
    {
        nullTree = true;
        leftTree = NULL;
        rightTree = NULL;
        parent = NULL;
    }
    
    void BinaryTree::setParent(BinaryTree *parent){
        this->parent = parent;
    }
    
    BinaryTree* BinaryTree::getParent(){
        return parent;
    }
    

    您的删除函数将如下所示:

    void delete_leaf_node(BinaryTree *bt, int val)
    {
        BinaryTree *temp;
        temp = search_val(bt, val);
        //If node does not exist in the tree, inform the user
        if(temp == NULL)
        {
            cout << "\n   " << val << " was not found in the tree" << endl; 
        }
        //Check if node is a leaf
        else if(temp->isLeaf())
        {
            // You must distinguish which child you are
            BinaryTree* parent = temp->getParent();
            BinaryTree* leftChild = parent->left;
            BinaryTree* rightChild = parent->right;
            if(leftChild == temp){
                parent->left = null;
            }
            if(rightChild == temp){
                parent->right = null;
            }
            delete temp;
            cout << "\n   Leaf " << temp->getData() << " deleted" << endl;
        }
        //Inform user that node is not a leaf
        else 
            cout << "\n   " << temp->getData() << " is not a Leaf" << endl; 
        //Display using In Order Traversal to see that the node was actually deleted    
        cout << "\n   In Order Traversal after deleting: " << endl << "\n   ";
        inOrderTraverse(bt);
        cout << endl;
    } 
    

    【讨论】:

    • 保存参考资料?我不确定我明白你的意思,也不知道你是怎么做的。
    • 所以当我创建节点并链接它们时,我必须在那里创建一个父指针?
    • 如果你有 BinaryTree.h 文件,我可以给出更具体的答案
    • @sean - 另一种选择是有一个带有“尾随”指针的搜索功能,这样当你找到你的节点时,你也会记住父节点。这是一个时空权衡。
    • @BoPersson 是的,在我看来,这更像是一个肮脏的解决方案,而且效率肯定较低,但如果你不删除很多(节点)并且不想弄乱你的代码,可以做一个好的解决方案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    相关资源
    最近更新 更多