①非递归拷贝
算法思想:利用双队列,在检索被拷贝树的左右子树时,当前树的检索也保持同样的路径,即可依次拷贝树的结点。采用队列是为了往树的深处检索(每次出队的是当前已拷贝的子女的父亲)。
template<class T>
BinaryTree<T>::BinaryTree(BinaryTree<T>& s)
{
if (s.root == NULL)
{
root = NULL;
}
else
{
root = new BinTreeNode<T>;
BinTreeNode<T> *p1 = s.root, *p2 = root;
p2->data = s.root->data;
queue<BinTreeNode<T>*>queue1, queue2;
queue1.push(s.root);
queue2.push(root);
while (!queue1.empty())
{
p1 = queue1.front();
p2 = queue2.front();
if (p1->leftChild != NULL)//先左后右,不为空则拷贝
{
BinTreeNode<T> *newNode = new BinTreeNode<T>(p1->leftChild->data);
p2->leftChild = newNode;
queue1.push(p1->leftChild);//保持相同行为
queue2.push(p2->leftChild);
}
if (p1->rightChild != NULL)
{
BinTreeNode<T> *newNode = new BinTreeNode<T>(p1->rightChild->data);
p2->rightChild = newNode;
queue1.push(p1->rightChild);
queue2.push(p2->rightChild);
}
queue1.pop();//出队后,下一次判定的是它的根结点
queue2.pop();
}
}
}
②递归拷贝
算法思想:二叉树拷贝函数中调用一个拷贝函数,在拷贝函数中递归。不再需要队列,只要保持传入的结点在树中的位置相同就行。这里的本树的传参是指针引用,是为了本树的root在函数中能够成功被赋值。如果只是传指针,root的指向不会改变,会导致拷贝失败。
//类中的声明:
BinaryTree(BinaryTree<T>& s) { copyOther(root, s.root); }//拷贝树,公有
void copyOther(BinTreeNode<T>* &thisSubTree, BinTreeNode<T> *otherSubTree);//本树拷贝别的树,私有
template<class T>
void BinaryTree<T>::copyOther(BinTreeNode<T>* &thisSubTree, BinTreeNode<T> *otherSubTree)
{
if (otherSubTree == NULL)
return;
thisSubTree = new BinTreeNode<T>;
thisSubTree->data = otherSubTree->data;
copyOther(thisSubTree->leftChild, otherSubTree->leftChild);
copyOther(thisSubTree->rightChild, otherSubTree->rightChild);
}