算法题25 二叉树的后序遍历变形之二叉树中和为某一值的路径
题目
输入一棵二叉树和一个整数, 打印出二叉树中结点值的和为输入整数的所有路径。从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。
分析
我们暂且将从树的根节点开始往下已知到叶节点所经过的节点形成的一条路径称为一条垂直路径。仔细模拟查找过程,当查找到一个叶节点时,要么转而访问父节点的右孩子(该叶节点为左孩子),要么返回上层父节点。因为路径打印的需要,在访问完左子树后,父节点仍然要保留缓存,等待查找右子树并打印符合条件的路径;当访问完右子树后,再一次访问该父节点,此时父节点的左右子树都查询过了,返回上层父节点。显然,在这个过程中,一个父节点会被访问到3次(第一次遍历,左孩子返回,右孩子返回),因此只保存父节点是不够的,还需要记录到底是第几次访问。这就是后序遍历啊!因此,用之前后序遍历的方法解此题
代码
1 void PrintSumPath2(TreeNode* root,int number) 2 { 3 if (!root) 4 { 5 cout<<"the tree is empty!"<<endl; 6 return; 7 } 8 9 stack<TreeNode*> s_parents; 10 map<TreeNode*,int> map_tag; 11 12 int sum=0; 13 14 TreeNode* node=root; 15 while(node||!s_parents.empty()) 16 { 17 if (map_tag.find(node)==map_tag.end())//节点没有遍历过,循环遍历至最左叶节点 18 { 19 while (node) 20 { 21 s_parents.push(node); 22 map_tag.insert(make_pair(node,1)); 23 24 sum+=node->value; 25 if (sum>number) 26 break; 27 28 node=node->pLeft; 29 } 30 31 if(sum==number&&node==NULL)//和等于特定值,且已遍历至子叶点 32 { 33 PrintSubPath(s_parents); 34 } 35 36 node=s_parents.top(); 37 //cout<<node->value<<endl; 38 sum-=node->value; 39 s_parents.pop(); 40 } 41 42 if (s_parents.empty()) 43 { 44 break; 45 } 46 47 node=s_parents.top(); 48 if (map_tag[node]==2)//如果左右子孩子都已经遍历过,pop返回 49 { 50 //cout<<node->value<<endl; 51 sum-=node->value; 52 s_parents.pop(); 53 }else //如果遍历标记=1,即只遍历过左孩子,转移到右子树继续遍历 54 { 55 map_tag[node]+=1; 56 node=node->pRight; 57 } 58 } 59 60 }