思路其实比较简单,采用递归来处理,采用两个容器来存储两个节点的所有子节点,然后逐个去递归比较。但是难点在于不考虑子树的顺序!
笔者第一次,想先排序(比如使用优先队列),把算法复杂度到max(O(mlogm,nlogn)).但是发现有可能两棵子树的根的值相等,但是下面的部分却不相等,此时比较会出出错。所以必须逐个比较,并把比较过确实相等的去重。
还有一点需要注意的是,如果采用对树中的每一棵子树,都试图从中找是否有相等的子树,若所有的都能找到则两个集合相等。这样也不正确,因为可能是集合1术语集合2.所以我们还要先比较下集合的大小。
using namespace std;
bool EqualTree(TreeNode *rt1, TreeNode<T>* rt2){
if(rt1==NULL && rt2 == NULL)
return true;
if((rt1==NULL && rt2!=NULL) || (rt1!=NULL && rt2=NULL))
return false;
if(rt1->data() != rt2->data()){
return false;
}
if(rt.isLeaf() && r2.isLeaf())
return true; //达到叶节点,不再递归直接返回
List<TreeNode *> l1,l2;
TreeNode * pointer1 = rt1,pointer2=rt2;
while(pointer1!=NULL){
l1.push_back(pointer1);
pointer1 = pointer1->RightSibling();
}
while(pointer2!=NULL){
l2.push_back(pointer2);
pointer2 = pointer2->RightSibling();
}
if(l1.size() != l2.size()) //防止出现子集相等
return false;
list<TreeNode *>::iterator it1, it2; // 子节点列表的迭代器
for(it1=l1.begin();it1<l1.end();it1++){
for(it2=l2.begin();it2<l2.end();it2++){
if(EqualTree(*it1,*it2)){ //递归处理,保证节点的子树也全相等
l2.erase(it2); //删掉,避免重复计算
break;
}
}
if(it2 == l2.end())
return false;
}
return true;
}
复制代码
算法最坏的情况下每个子树对都需要比较一次,即任意都需要比较一次,复杂度为O(mn)。