先序遍历
参考:http://zhedahht.blog.163.com/
- 请完成一个函数,输入一个二叉树,输出它的镜像。
- 输入两颗二叉树A和B,判断B是不是A的子结构。
- 输入一棵二叉树和一个整数,打印出二叉树中结点值和为该整数的所有路径。
1、思路:
先序遍历。对每个子树的根结点,交换左右子树的指向,终止条件是到达叶子节点,就不需要交换左右子节点了。
MirrorRecursively
1 void MirrorRecursively(BinaryTreeNode *pNode) 2 { 3 if((pNode == NULL) || (pNode->m_pLeft == NULL && pNode->m_pRight==NULL)) 4 return; 5 6 BinaryTreeNode *pTemp = pNode->m_pLeft; 7 pNode->m_pLeft = pNode->m_pRight; 8 pNode->m_pRight = pTemp; 9 10 if(pNode->m_pLeft) 11 MirrorRecursively(pNode->m_pLeft); 12 13 if(pNode->m_pRight) 14 MirrorRecursively(pNode->m_pRight); 15 }
2、思路:
分两步进行:第一步、先判断根节点是否相同;第二步、再判断子节点是否相同。终止条件是A树到达叶子节点说明false,或是B树到达叶子节点说明true。判断过程中任何遇到不相等的结点都跳出循环。
HasSubtree
1 bool HasSubtree(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2) 2 { 3 bool result = false; 4 5 if(pRoot1 != NULL && pRoot2 != NULL) 6 { 7 if(pRoot1->m_nValue == pRoot2->m_nValue) 8 result = DoesTree1HaveTree2(pRoot1, pRoot2); 9 if(!result) 10 result = HasSubtree(pRoot1->m_pLeft, pRoot2); 11 if(!result) 12 result = HasSubtree(pRoot1->m_pRight, pRoot2); 13 } 14 15 return result; 16 } 17 18 bool DoesTree1HaveTree2(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2) 19 { 20 if(pRoot2 == NULL) 21 return true; 22 23 if(pRoot1 == NULL) 24 return false; 25 26 if(pRoot1->m_nValue != pRoot2->m_nValue) 27 return false; 28 29 return DoesTree1HaveTree2(pRoot1->m_pLeft, pRoot2->m_pLeft) && 30 DoesTree1HaveTree2(pRoot1->m_pRight, pRoot2->m_pRight); 31 }
3、思路:
先序遍历。每次将结点值放入路径和中,终止条件是达到叶子节点,判断和是否相同。再退回到父结点时,需要从路径中重新拿出该结点。
FindPath
1 void FindPath(BinaryTreeNode* pRoot, int expectedSum) 2 { 3 if(pRoot == NULL) 4 return; 5 6 std::vector<int> path; 7 int currentSum = 0; 8 FindPath(pRoot, expectedSum, path, currentSum); 9 } 10 11 void FindPath 12 ( 13 BinaryTreeNode* pRoot, 14 int expectedSum, 15 std::vector<int>& path, 16 int& currentSum 17 ) 18 { 19 currentSum += pRoot->m_nValue; 20 path.push_back(pRoot->m_nValue); 21 22 // 如果是叶结点,并且路径上结点的和等于输入的值 23 // 打印出这条路径 24 bool isLeaf = pRoot->m_pLeft == NULL && pRoot->m_pRight == NULL; 25 if(currentSum == expectedSum && isLeaf) 26 { 27 printf("A path is found: "); 28 std::vector<int>::iterator iter = path.begin(); 29 for(; iter != path.end(); ++ iter) 30 printf("%d\t", *iter); 31 32 printf("\n"); 33 } 34 35 // 如果不是叶结点,则遍历它的子结点 36 if(pRoot->m_pLeft != NULL) 37 FindPath(pRoot->m_pLeft, expectedSum, path, currentSum); 38 if(pRoot->m_pRight != NULL) 39 FindPath(pRoot->m_pRight, expectedSum, path, currentSum); 40 41 // 在返回到父结点之前,在路径上删除当前结点, 42 // 并在currentSum中减去当前结点的值 43 currentSum -= pRoot->m_nValue; 44 path.pop_back(); 45 }