【问题标题】:Binary Search Tree: clone method?二叉搜索树:克隆方法?
【发布时间】:2021-12-01 11:44:56
【问题描述】:

我想弄清楚我应该如何实现clone() 方法。

现在代码不打印任何东西。这是C++中的二叉搜索树问题,需要克隆树的右侧和左侧,包括递归函数。

函数应该返回节点的地址。

#include <iostream>
using namespace std;

//=====================================================================
struct Node 
{
    int x;
    Node * left;
    Node * right;
    Node(){left = NULL; right = NULL;}
    
    Node(int d, Node* l = 0, Node* r = 0)
    {
        x = d;
        left = l;
        right = r;
    }
};

//=====================================================================
class Tree 
{
  private:
    Node * root;
    
  public:
    Tree() 
    {
        root = NULL;
    }
    //=================================================================
    // can you please suggest how should I implement clone method ?
    
    //-----------------------------------------
    // clone(), makes a deep copy
    //
    Node* clone(Node* n) const
    {
        return 0;
    }
    //-----------------------------------------
    // copy constructor
    //
    Tree(const Tree &t) 
    {
        root = t.root;
    }
    //-----------------------------------------------------------------
    // Iterative find
    //
    public: Node* find(int key)
    {
        return 0;
    }
    //-----------------------------------------------------------------
    // Recursive find
    //
    public: Node* find2(int key) { return find2(key, root); }
    private: Node* find2(int key, Node* n)
    {
        return 0;
    }
    //-----------------------------------------------------------------
    // Count Nodes
    //
    public: int node_count() { return node_count(root); }
    private: int node_count(Node* n)
    {
        return 0;
    }
    //-----------------------------------------------------------------
    // Maximum depth
    // Ok to use if statement instead of max function
    //
    public: int depth() { return depth(root); }
    private: int depth(Node* n)
    {
        return 0;
    }
    // End of the functions to be implemented.
    //=================================================================
    
    public:  
    //-----------------------------------------------------------------
    void insert(int x) 
    {
        Node * ptr = new Node(x);


        cout << "\n-------------------------------------" << endl;
        cout << "Node Address: " << ptr << endl;

        if (root == NULL)
            root = ptr;
        else 
        {
            Node * temp = root;

            while (true) 
            {
                if (temp -> x > x) 
                {
                    if (temp -> left == NULL) {
                        cout << "Node Parent Address: " << temp << endl;
                        cout << "Node Parent Value: " << temp -> x << endl;
                        temp -> left = ptr;
                        break;
                    } else
                        temp = temp -> left;
                } else 
                {
                    if (temp -> right == NULL) 
                    {
                        cout << "Node Parent Address: " << temp << endl;
                        cout << "Node Parent Value: " << temp -> x << endl;
                        temp -> right = ptr;
                        break;
                    } else
                        temp = temp -> right;
                }
            }
        }

        cout << "Root: " << root << endl;
        cout << "-------------------------------------" << endl;
    }
        
    //-----------------------------------------------------------------
    public: void inOrder(){ inOrder(root); }
    private: void inOrder(Node * temp) {
        if (temp != NULL) 
        {
            inOrder(temp -> left);
            cout << temp -> x << " ";
            inOrder(temp -> right);
        }
    }
        
    //-----------------------------------------------------------------
    public: void preOrder(){ inOrder(root); }
    private: void preOrder(Node * temp) 
    {
        if (temp != NULL) {
            cout << temp -> x << " ";
            preOrder(temp -> left);
            preOrder(temp -> right);
        }
    }
        
    //-----------------------------------------------------------------
    public: void postOrder(){ inOrder(root); }
    private: void postOrder(Node * temp) 
    {
        if (temp != NULL) {
            postOrder(temp -> left);
            postOrder(temp -> right);
            cout << temp -> x << " ";
        }
    }
    //-----------------------------------------------------------------
    public: void serial(ostream &os) const { serial(os, root); }
    private: void serial(ostream &os, Node *n) const
    {
        if (!n) os << '-';
        else
        {
            os << n->x << ' ';
            serial(os, n->left); os << ' ';
            serial(os, n->right);
        }
    }
        
    //-----------------------------------------------------------------
    public: Node * getRoot() {
        return root;
    }
        
    //-----------------------------------------------------------------
    public: void display(){ display(root); }
    private: void display(Node * temp) 
    {
        if (temp != NULL) {
            cout << endl;
            cout << "Parent: " << temp -> x << endl;
            cout << " Left Child of " << temp -> x << ": ";
            if (temp -> left == NULL)
                cout << "NULL" << endl;
            else
                cout << temp -> left -> x << endl;

            cout << " Right Child of " << temp -> x << ": ";
            if (temp -> right == NULL)
                cout << "NULL" << endl;
            else
                cout << temp -> right -> x << endl;
            display(temp -> left);
            display(temp -> right);
        }
    }
      
    public:   
    //-----------------------------------------------------------------
    bool isEmpty() 
    {
        if (root == NULL)
            return true;

        return false;
    }
    
        
    //-----------------------------------------------------------------
    void removeAll(int value) 
    {
        while (true) 
        {
            Node * temp = root, * ptemp = root;

            while (temp != NULL && temp -> x != value) 
            {
                ptemp = temp;
                if (temp -> x < value)
                    temp = temp -> right;
                else if (temp -> x > value)
                    temp = temp -> left;
            }

            if (temp == NULL) 
            {
                cout << "All nodes cotaining " << value << " are deleted" << endl;
                break;
            } else 
            {
                if (temp -> left == NULL && temp -> right == NULL) 
                {
                    if (temp == root)
                        root = NULL;
                    else if (ptemp -> left == temp)
                        ptemp -> left = NULL;
                    else if (ptemp -> right == temp)
                        ptemp -> right = NULL;
                } else if (temp -> left == NULL && temp -> right != NULL) 
                {
                    if (temp == root)
                        root = temp -> right;
                    else if (ptemp -> left == temp)
                        ptemp -> left = temp -> right;
                    else if (ptemp -> right == temp)
                        ptemp -> right = temp -> left;
                } else if (temp -> right == NULL && temp -> left != NULL) 
                {
                    if (temp == root)
                        root = temp -> left;
                    else if (ptemp -> left == temp)
                        ptemp -> left = temp -> left;
                    else if (ptemp -> right == temp)
                        ptemp -> right = temp -> right;
                } else if (temp -> left != NULL && temp -> right != NULL) 
                {
                    Node * tempHolder = temp, * ptempHolder = temp;

                    while (tempHolder -> left != NULL) 
                    {
                        ptempHolder = tempHolder;
                        tempHolder = tempHolder -> left;
                    }

                    temp -> x = tempHolder -> x;
                    ptempHolder -> left = tempHolder -> right;

                    temp = tempHolder;
                }

                delete temp;
                cout << "Node Removed Successfully." << endl;
            }
        }
    }
        
    //-----------------------------------------------------------------
    void remove(int value) 
    {
        Node * temp = root, * ptemp = root;

        while (temp != NULL && temp -> x != value) 
        {
            ptemp = temp;
            if (temp -> x < value)
                temp = temp -> right;
            else if (temp -> x > value)
                temp = temp -> left;
        }

        if (temp == NULL) {
            cout << "Value Not Found...." << endl;
        } else 
        {
            if (temp -> left == NULL && temp -> right == NULL) 
            {
                if (temp == root)
                    root = NULL;
                else if (ptemp -> left == temp)
                    ptemp -> left = NULL;
                else if (ptemp -> right == temp)
                    ptemp -> right = NULL;
            } else if (temp -> left == NULL && temp -> right != NULL) 
            {
                if (temp == root)
                    root = temp -> right;
                else if (ptemp -> left == temp)
                    ptemp -> left = temp -> right;
                else if (ptemp -> right == temp)
                    ptemp -> right = temp -> left;
            } else if (temp -> right == NULL && temp -> left != NULL) 
            {
                if (temp == root)
                    root = temp -> left;
                else if (ptemp -> left == temp)
                    ptemp -> left = temp -> left;
                else if (ptemp -> right == temp)
                    ptemp -> right = temp -> right;
            } else if (temp -> left != NULL && temp -> right != NULL) 
            {
                Node * tempHolder = temp, * ptempHolder = temp;

                while (tempHolder -> left != NULL) 
                {
                    ptempHolder = tempHolder;
                    tempHolder = tempHolder -> left;
                }

                temp -> x = tempHolder -> x;
                ptempHolder -> left = tempHolder -> right;

                temp = tempHolder;
            }

            delete temp;
            cout << "Node Removed Successfully." << endl;
        }
    }
    
    
        
    //-----------------------------------------------------------------
    void deleteAllNodes(Node * temp) {
        if (temp != NULL) {
            deleteAllNodes(temp -> left);
            deleteAllNodes(temp -> right);
            cout << "Address: " << temp << endl;
            cout << "Value: " << temp -> x << endl << endl;
            delete temp;
        }
    }
        
    //-----------------------------------------------------------------
    // Iterative find
    //
    ~Tree() {
        cout << "Below Nodes Deleted Successfully:" << endl;
        deleteAllNodes(root);
    }
    
};

//---------------------------------------------
// Operator Overloading
//
ostream& operator<<(ostream &os, const Tree& t)
{
    t.serial(os);
    return os;
}

//=====================================================================
int main(){
    cout << "BST_Serial-01\n";
    Tree T;
    T.insert(50);
    T.insert(20);
    T.insert(80);
    T.insert(60);
    T.insert(90);
    
    cout << "Node count = " << T.node_count() << endl;
    cout << "depth = " << T.depth() << endl;
    cout << "find(60) = " << T.find(60) << endl;
    cout << "find(65) = " << T.find(65) << endl;
    cout << "find2(60) = " << T.find2(60) << endl;
    cout << "find2(65) = " << T.find2(65) << endl;
    
    Tree S = Tree(T);
    cout << "S = " << S << endl;

    T.insert(100);
    cout << "After insert 100\n";
    cout << "T = " << T << endl;
    cout << "S = " << S << endl;
    return 0;
}

【问题讨论】:

  • 查看这个答案,它在 Java 中,但逻辑相似。 stackoverflow.com/questions/16098362/…
  • Tree(const Tree &amp;t) 未正确实现复制构造函数。它会给你留下两个Trees,它们都指向同一组Nodes,这立即是一个错误,最终是一个致命的错误。正确实现复制构造函数,克隆问题就消失了:复制构造函数完成了这项工作。
  • 为什么? 50 年来我从来没有克隆过 BST。为什么不使用 Stroustrup 在设计 C++ 时打算使用的复制构造器,而不是从其他语言导入习语?

标签: c++ binary-search-tree clone


【解决方案1】:

查看这个答案,它在 Java 中,但逻辑相似。

How to deep copy a Binary Tree?

使用前序遍历:

template<typename T> NODE<T>* BST<T>::copyTree(NODE<T>* root) 
{ 
    NODE<T>* copyNode = NULL; 
    if (root) 
    { 
        copyNode = new NODE<T>(); 
        copyNode->data = root->data; 
        copyNode->left = copyTree(root->left); 
        copyNode->right = copyTree(root->right); 
    } 
    return copyNode; 
} 

基本上你传递树的根,它递归地复制左右子树,直到它到达基本情况。

【讨论】:

  • C++ 有复制构造函数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-08
  • 2014-04-19
  • 2013-02-07
  • 2013-11-21
相关资源
最近更新 更多