题目:输入二叉树和一个整数,打印出二叉树中节点值的和为输入整数的所有路径。从数的根节点开始往下一直到叶节点所经过的节点形成一条路径。二叉树的接待你定义如下:
struct BinaryTreeNode {
int m_nValue;
BinaryTreeNode *m_pLeft;
BinaryTreeNode *m_pRight;
};
思路:
递归,函数参数中维护”路径“,回溯。
编译环境:ArchLinux+Clang3.3, C++11
实现一:
#include <iostream>
#include <vector>
#include <cstring>
#include <cctype>
using namespace std;
struct BinaryTreeNode {
int m_nValue;
BinaryTreeNode *m_pLeft;
BinaryTreeNode *m_pRight;
};
void do_printPath(BinaryTreeNode *pRoot, vector<int>& path, int expectedSum, int pathSum);
/** Wrapper: 打印符合条件的路径 *//
void printPath(BinaryTreeNode *pRoot, int expectedSum)
{
if (pRoot == nullptr) return;
vector<int> path;
do_printPath(pRoot, path, expectedSum, 0);
}
void do_printPath(BinaryTreeNode *pRoot, vector<int>& path, int expectedSum, int pathSum)
{
path.push_back(pRoot->m_nValue);
pathSum += pRoot->m_nValue;
bool isLeaf = !pRoot->m_pLeft && !pRoot->m_pRight;
if (isLeaf && pathSum == expectedSum) {
for (auto i : path) {
cout << i << ' ';
}
cout << endl;
}
/** 递归 **/
if (pRoot->m_pLeft)
do_printPath(pRoot->m_pLeft, path, expectedSum, pathSum);
if (pRoot->m_pRight)
do_printPath(pRoot->m_pRight, path, expectedSum, pathSum);
path.pop_back(); // 回溯
}
int getNum(const char *start, const char *end, int *moved)
{
int n = 0;
while (start < end && isdigit(*start)) {
(*moved)++;
n *= 10;
n += *start - '0';
start++;
}
return n;
}
/**
* 根据二叉树的字符表示形式(形如"1(2,3(,4))")创建二叉树
* 区间:[start, end)
**/
BinaryTreeNode *createTree(const char *start, const char *end)
{
if (start >= end) {
return nullptr;
}
// if (end - start == 1) {
// return new BinaryTreeNode{*start-'0', nullptr, nullptr};
// }
int rootLen = 0;
int rootValue = getNum(start, end, &rootLen);
if (start + rootLen == end) {
return new BinaryTreeNode{rootValue, nullptr, nullptr};
}
const char *start1 = start + rootLen + 1;
const char *end1 = start + rootLen + 1;
int cnt = 0;
while (true) {
if (*end1 == '(') cnt++;
if (*end1 == ')') cnt--;
if (*end1 == ',' && cnt == 0) break;
end1++;
}
const char *start2 = end1+1;
const char *end2 = end1+1;
cnt = 0;
while (true) {
if (*end2 == '(') cnt++;
if (*end2 == ')' && cnt == 0) break;
if (*end2 == ')') cnt--;
end2++;
}
return new BinaryTreeNode{rootValue,
createTree(start1, end1),
createTree(start2, end2)};
}
BinaryTreeNode *createTree(const char *str)
{
return createTree(str, str + strlen(str));
}
/** 打印二叉树 **/
void printTree(BinaryTreeNode *pRoot){
if (!pRoot) return;
cout << pRoot->m_nValue;
if (pRoot->m_pLeft || pRoot->m_pRight) cout << '(';
if (pRoot->m_pLeft) {
printTree(pRoot->m_pLeft);
}
if (pRoot->m_pLeft || pRoot->m_pRight) cout << ',';
if (pRoot->m_pRight) {
printTree(pRoot->m_pRight);
}
if (pRoot->m_pLeft || pRoot->m_pRight) cout << ')';
}
int main()
{
BinaryTreeNode *pRoot = createTree("10(5(4,7),12)");
printTree(pRoot); cout << endl;
printPath(pRoot, 22);
}