【发布时间】: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 &t)未正确实现复制构造函数。它会给你留下两个Trees,它们都指向同一组Nodes,这立即是一个错误,最终是一个致命的错误。正确实现复制构造函数,克隆问题就消失了:复制构造函数完成了这项工作。 -
为什么? 50 年来我从来没有克隆过 BST。为什么不使用 Stroustrup 在设计 C++ 时打算使用的复制构造器,而不是从其他语言导入习语?
标签: c++ binary-search-tree clone