1、二叉树定义
typedef struct BTreeNodeElement_t_ { void *data; } BTreeNodeElement_t; typedef struct BTreeNode_t_ { BTreeNodeElement_t *m_pElemt; struct BTreeNode_t_ *m_pLeft; struct BTreeNode_t_ *m_pRight; } BTreeNode_t;
2、比較两个二叉树结构是否同样,不涉及存储的数据
(1)递归方式
假设两个二叉树pRoot都为空树,则自然同样,返回true。
假设两个二叉树pRoot一个为空树,还有一个不为空树。则不同样,返回false;
假设两个二叉树都不为空树。则须要分别比較左右子树后,依据比較结果共同判定。仅仅要有一个为false,则返回false。
bool BTreeCompare( BTreeNode_t *pRoot1, BTreeNode_t *pRoot2) { //假设都为空树,则同样 if( pRoot1 == NULL && pRoot2 == NULL ) return true; //假设一个为空。一个不为空。则不同样 if( ( pRoot1 != NULL && pRoot2 == NULL ) || ( pRoot1 == NULL && pRoot2 != NULL ) ) return false; //假设都不为空,则 须要比較左右子树后,再依据比較结果断定 bool leftCmp = BTreeCompare( pRoot1->m_pLeft, pRoot2->m_pLeft); bool rightCmp = BTreeCompare( pRoot1->m_pRight, pRoot2->m_pRight); return ( leftCmp && rightCmp ); }
(2)非递归方式
借助队列实现
实现算法:
首先将给定根节点pRoot1和pRoot2都入队
第一步:当两个队列未空时,分别获取两个树的当前层次中节点总数(即当前队列中节点个数)。先比較节点个数是否同样,假设不同样,则两个树自然不同;假设节点个数同样,须要出队进行比較。
假设有一个队列未空,则退出比較。
第二步:假设有一个队列未空,则清空队列并返回不同。
bool BTreeCompare(BTreeNode_t *pRoot1, BTreeNode_t *pRoot2) { if( pRoot1 == NULL && pRoot2 == NULL ) return false; queue <BTreeNode_t *> que1; queue <BTreeNode_t *> que2; que1.push(pRoot1); que2.push(pRoot2); int curLevelNodeTotal1 = 0; int curLevelNodeTotal2 = 0; bool flag = true; //作为比較不一致时跳出标识 while( ( !que1.empty()) && ( !que2.empty())) //当两个队列均不为空时。才进行比較 { curLevelNodeTotal1 = que1.size(); //获取树1的当前层节点总数 curLevelNodeTotal2 = que2.size(); //获取树2的当前层节点总数 if( curLevelNodeTotal1 != curLevelNodeTotal2){ flag = false;//当前层节点总数都不一致,不须要比較了,直接跳出 break; } int cnt1 = 0;//遍历本层节点时的计数器 int cnt2 = 0; while( cnt1 < curLevelNodeTotal1 && cnt2 < curLevelNodeTotal2){ ++cnt1; ++cnt2; pRoot1 = que1.front(); que1.pop(); pRoot2 = que2.front(); que2.pop(); //推断pRoot1和pRoot2左右节点结构是否同样 if( ( pRoot1->m_pLeft != NULL && pRoot2->m_pLeft == NULL ) || ( pRoot1->m_pLeft == NULL && pRoot2->m_pLeft != NULL ) || ( pRoot1->m_pRight != NULL && pRoot2->m_pRight == NULL ) || ( pRoot1->m_pRight == NULL && pRoot2->m_pRight != NULL ) ){ flag = false; break; } //将左右节点入队 if( pRoot1->m_pLeft != NULL ) que1.push( pRoot1->m_pLeft); if( pRoot1->m_pRight != NULL ) que1.push( pRoot1->m_pRight); if( pRoot2->m_pLeft != NULL ) que2.push( pRoot2->m_pLeft); if( pRoot2->m_pRight != NULL ) que2.push( pRoot2->m_pRight); } if( flag == false ) break; } //假设比較标志为false。则不同样 if( flag == false ){ while( !que1.empty() ) que1.pop(); while( !que2.empty()) que2.pop(); return false; } return true; }
3、比較两个二叉树结构和数据是否同一时候同样。即两个一模一样的树
与上面的不同之处在于:在比較结构是否同样之后。须要比較当前节点的数据是否一致。
算法是一致的,仅仅须要加入一行代码就可以。
(1)递归方式:
bool BTreeCompare( BTreeNode_t *pRoot1, BTreeNode_t *pRoot2) { //假设都为空树,则同样 if( pRoot1 == NULL && pRoot2 == NULL ) return true; //假设一个为空。一个不为空,则不同样 if( ( pRoot1 != NULL && pRoot2 == NULL ) || ( pRoot1 == NULL && pRoot2 != NULL ) ) return false; //比較当前节点中的数据 if( pRoot1->m_pElemt != pRoot2->m_pElemt) return false; //假设都不为空。则 须要比較左右子树后。再依据比較结果断定 bool leftCmp = BTreeCompare( pRoot1->m_pLeft, pRoot2->m_pLeft); bool rightCmp = BTreeCompare( pRoot1->m_pRight, pRoot2->m_pRight); return ( leftCmp && rightCmp ); }
bool BTreeCompare(BTreeNode_t *pRoot1, BTreeNode_t *pRoot2) { if( pRoot1 == NULL && pRoot2 == NULL ) return false; queue <BTreeNode_t *> que1; queue <BTreeNode_t *> que2; que1.push(pRoot1); que2.push(pRoot2); int curLevelNodeTotal1 = 0; int curLevelNodeTotal2 = 0; bool flag = true; //作为比較不一致时跳出标识 while( ( !que1.empty()) && ( !que2.empty())) //当两个队列均不为空时,才进行比較 { curLevelNodeTotal1 = que1.size(); //获取树1的当前层节点总数 curLevelNodeTotal2 = que2.size(); //获取树2的当前层节点总数 if( curLevelNodeTotal1 != curLevelNodeTotal2){ flag = false;//当前层节点总数都不一致。不须要比較了,直接跳出 break; } int cnt1 = 0;//遍历本层节点时的计数器 int cnt2 = 0; while( cnt1 < curLevelNodeTotal1 && cnt2 < curLevelNodeTotal2){ ++cnt1; ++cnt2; pRoot1 = que1.front(); que1.pop(); pRoot2 = que2.front(); que2.pop(); //比較当前节点中数据是否一致 if( pRoot1->m_pElemt != pRoot2->m_pElemt ){ flag = false; break; } //推断pRoot1和pRoot2左右节点结构是否同样 if( ( pRoot1->m_pLeft != NULL && pRoot2->m_pLeft == NULL ) || ( pRoot1->m_pLeft == NULL && pRoot2->m_pLeft != NULL ) || ( pRoot1->m_pRight != NULL && pRoot2->m_pRight == NULL ) || ( pRoot1->m_pRight == NULL && pRoot2->m_pRight != NULL ) ){ flag = false; break; } //将左右节点入队 if( pRoot1->m_pLeft != NULL ) que1.push( pRoot1->m_pLeft); if( pRoot1->m_pRight != NULL ) que1.push( pRoot1->m_pRight); if( pRoot2->m_pLeft != NULL ) que2.push( pRoot2->m_pLeft); if( pRoot2->m_pRight != NULL ) que2.push( pRoot2->m_pRight); } if( flag == false ) break; } //假设比較标志为false。则不同样 if( flag == false ){ while( !que1.empty() ) que1.pop(); while( !que2.empty()) que2.pop(); return false; } return true; }