剑指oofer 25 - 二叉树中和为某一值的路径
2015-06-02 14:41
274 查看
可以按照先序遍历的方式访问二叉树,这样可以确保根先于子树被访问到,另外需准备一个栈(可用数组代替,因为需要打印路径),每访问一个结点,就统计当前路径和以及当前结点是否是叶子结点,如果满足则打印,否则递归其左右子树,需要注意的是在返回到父节点时,需要将栈顶元素删除。
#include <iostream>
#include<vector>
using namespace std;
struct BinaryTreeNode
{
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
};
BinaryTreeNode* CreateBinaryTreeNode(int value)
{
BinaryTreeNode *head = new BinaryTreeNode[sizeof(BinaryTreeNode )];
head->m_nValue = value;
head->m_pLeft = head->m_pRight = NULL;
return head;
}
void ConnectTreeNodes(BinaryTreeNode* root ,BinaryTreeNode* left, BinaryTreeNode* right)
{
if(root != NULL)
{
root->m_pLeft = left;
root->m_pRight = right;
}
}
void DestroyTree(BinaryTreeNode* root)
{
if(root !=NULL)
{
BinaryTreeNode* left = root->m_pLeft;
BinaryTreeNode* right= root->m_pRight;
delete root;
root=NULL;
DestroyTree(left);
DestroyTree( right);
}
}
void FindPath
(
BinaryTreeNode* pRoot,
int expectedSum,
std::vector<int>& path, //引用
int& currentSum //引用
)
{
if(pRoot == NULL)
return;
currentSum += pRoot->m_nValue; //累加节点值 先序遍历
path.push_back(pRoot->m_nValue); //添加到路径
bool isLeaf = pRoot->m_pLeft==NULL && pRoot->m_pRight==NULL;
if( currentSum == expectedSum && isLeaf) // 叶结点,且结点的和相等,,打印出这条路径
{
for(int i=0;i<path.size();i++)
cout<<path[i]<<" ";
cout<<endl;
}
if(pRoot->m_pLeft)
FindPath(pRoot->m_pLeft,expectedSum,path,currentSum );
if(pRoot->m_pRight)
FindPath(pRoot->m_pRight,expectedSum,path,currentSum );
currentSum -= pRoot->m_nValue; //在currentSum中减去当前结点的值
path.pop_back(); //在返回到父结点之前,在路径上删除当前结点,
}
// ====================测试代码====================
void Test(char* testName, BinaryTreeNode* pRoot, int expectedSum)
{
if(testName != NULL)
printf("%s begins:\n", testName);
std::vector<int> path;
int currentSum = 0;
FindPath(pRoot, expectedSum, path, currentSum);
printf("\n");
}
// 10
// / \
// 5 12
// /\
// 4 7
// 有两条路径上的结点和为22
void Test1()
{
BinaryTreeNode* pNode10 = CreateBinaryTreeNode(10);
BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
BinaryTreeNode* pNode12 = CreateBinaryTreeNode(12);
BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
BinaryTreeNode* pNode7 = CreateBinaryTreeNode(7);
ConnectTreeNodes(pNode10, pNode5, pNode12);
ConnectTreeNodes(pNode5, pNode4, pNode7);
printf("Two paths should be found in Test1.\n");
Test("Test1", pNode10, 22);
DestroyTree(pNode10);
}
// 10
// / \
// 5 12
// /\
// 4 7
// 没有路径上的结点和为15
void Test2()
{
BinaryTreeNode* pNode10 = CreateBinaryTreeNode(10);
BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
BinaryTreeNode* pNode12 = CreateBinaryTreeNode(12);
BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
BinaryTreeNode* pNode7 = CreateBinaryTreeNode(7);
ConnectTreeNodes(pNode10, pNode5, pNode12);
ConnectTreeNodes(pNode5, pNode4, pNode7);
printf("No paths should be found in Test2.\n");
Test("Test2", pNode10, 15);
DestroyTree(pNode10);
}
// 5
// /
// 4
// /
// 3
// /
// 2
// /
// 1
// 有一条路径上面的结点和为15
void Test3()
{
BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3);
BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2);
BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1);
ConnectTreeNodes(pNode5, pNode4, NULL);
ConnectTreeNodes(pNode4, pNode3, NULL);
ConnectTreeNodes(pNode3, pNode2, NULL);
ConnectTreeNodes(pNode2, pNode1, NULL);
printf("One path should be found in Test3.\n");
Test("Test3", pNode5, 15);
DestroyTree(pNode5);
}
// 1
// \
// 2
// \
// 3
// \
// 4
// \
// 5
// 没有路径上面的结点和为16
void Test4()
{
BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1);
BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2);
BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3);
BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
ConnectTreeNodes(pNode1, NULL, pNode2);
ConnectTreeNodes(pNode2, NULL, pNode3);
ConnectTreeNodes(pNode3, NULL, pNode4);
ConnectTreeNodes(pNode4, NULL, pNode5);
printf("No paths should be found in Test4.\n");
Test("Test4", pNode1, 16);
DestroyTree(pNode1);
}
// 树中只有1个结点
void Test5()
{
BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1);
printf("One path should be found in Test5.\n");
Test("Test5", pNode1, 1);
DestroyTree(pNode1);
}
// 树中没有结点
void Test6()
{
printf("No paths should be found in Test6.\n");
Test("Test6", NULL, 0);
}
int main(int argc, char* argv[])
{
Test1();
Test2();
Test3();
Test4();
Test5();
Test6();
return 0;
}
#include <iostream>
#include<vector>
using namespace std;
struct BinaryTreeNode
{
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
};
BinaryTreeNode* CreateBinaryTreeNode(int value)
{
BinaryTreeNode *head = new BinaryTreeNode[sizeof(BinaryTreeNode )];
head->m_nValue = value;
head->m_pLeft = head->m_pRight = NULL;
return head;
}
void ConnectTreeNodes(BinaryTreeNode* root ,BinaryTreeNode* left, BinaryTreeNode* right)
{
if(root != NULL)
{
root->m_pLeft = left;
root->m_pRight = right;
}
}
void DestroyTree(BinaryTreeNode* root)
{
if(root !=NULL)
{
BinaryTreeNode* left = root->m_pLeft;
BinaryTreeNode* right= root->m_pRight;
delete root;
root=NULL;
DestroyTree(left);
DestroyTree( right);
}
}
void FindPath
(
BinaryTreeNode* pRoot,
int expectedSum,
std::vector<int>& path, //引用
int& currentSum //引用
)
{
if(pRoot == NULL)
return;
currentSum += pRoot->m_nValue; //累加节点值 先序遍历
path.push_back(pRoot->m_nValue); //添加到路径
bool isLeaf = pRoot->m_pLeft==NULL && pRoot->m_pRight==NULL;
if( currentSum == expectedSum && isLeaf) // 叶结点,且结点的和相等,,打印出这条路径
{
for(int i=0;i<path.size();i++)
cout<<path[i]<<" ";
cout<<endl;
}
if(pRoot->m_pLeft)
FindPath(pRoot->m_pLeft,expectedSum,path,currentSum );
if(pRoot->m_pRight)
FindPath(pRoot->m_pRight,expectedSum,path,currentSum );
currentSum -= pRoot->m_nValue; //在currentSum中减去当前结点的值
path.pop_back(); //在返回到父结点之前,在路径上删除当前结点,
}
// ====================测试代码====================
void Test(char* testName, BinaryTreeNode* pRoot, int expectedSum)
{
if(testName != NULL)
printf("%s begins:\n", testName);
std::vector<int> path;
int currentSum = 0;
FindPath(pRoot, expectedSum, path, currentSum);
printf("\n");
}
// 10
// / \
// 5 12
// /\
// 4 7
// 有两条路径上的结点和为22
void Test1()
{
BinaryTreeNode* pNode10 = CreateBinaryTreeNode(10);
BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
BinaryTreeNode* pNode12 = CreateBinaryTreeNode(12);
BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
BinaryTreeNode* pNode7 = CreateBinaryTreeNode(7);
ConnectTreeNodes(pNode10, pNode5, pNode12);
ConnectTreeNodes(pNode5, pNode4, pNode7);
printf("Two paths should be found in Test1.\n");
Test("Test1", pNode10, 22);
DestroyTree(pNode10);
}
// 10
// / \
// 5 12
// /\
// 4 7
// 没有路径上的结点和为15
void Test2()
{
BinaryTreeNode* pNode10 = CreateBinaryTreeNode(10);
BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
BinaryTreeNode* pNode12 = CreateBinaryTreeNode(12);
BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
BinaryTreeNode* pNode7 = CreateBinaryTreeNode(7);
ConnectTreeNodes(pNode10, pNode5, pNode12);
ConnectTreeNodes(pNode5, pNode4, pNode7);
printf("No paths should be found in Test2.\n");
Test("Test2", pNode10, 15);
DestroyTree(pNode10);
}
// 5
// /
// 4
// /
// 3
// /
// 2
// /
// 1
// 有一条路径上面的结点和为15
void Test3()
{
BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3);
BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2);
BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1);
ConnectTreeNodes(pNode5, pNode4, NULL);
ConnectTreeNodes(pNode4, pNode3, NULL);
ConnectTreeNodes(pNode3, pNode2, NULL);
ConnectTreeNodes(pNode2, pNode1, NULL);
printf("One path should be found in Test3.\n");
Test("Test3", pNode5, 15);
DestroyTree(pNode5);
}
// 1
// \
// 2
// \
// 3
// \
// 4
// \
// 5
// 没有路径上面的结点和为16
void Test4()
{
BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1);
BinaryTreeNode* pNode2 = CreateBinaryTreeNode(2);
BinaryTreeNode* pNode3 = CreateBinaryTreeNode(3);
BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);
BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
ConnectTreeNodes(pNode1, NULL, pNode2);
ConnectTreeNodes(pNode2, NULL, pNode3);
ConnectTreeNodes(pNode3, NULL, pNode4);
ConnectTreeNodes(pNode4, NULL, pNode5);
printf("No paths should be found in Test4.\n");
Test("Test4", pNode1, 16);
DestroyTree(pNode1);
}
// 树中只有1个结点
void Test5()
{
BinaryTreeNode* pNode1 = CreateBinaryTreeNode(1);
printf("One path should be found in Test5.\n");
Test("Test5", pNode1, 1);
DestroyTree(pNode1);
}
// 树中没有结点
void Test6()
{
printf("No paths should be found in Test6.\n");
Test("Test6", NULL, 0);
}
int main(int argc, char* argv[])
{
Test1();
Test2();
Test3();
Test4();
Test5();
Test6();
return 0;
}
相关文章推荐
- CSS选择器
- js获取窗口的位置
- 54 js 轮播图片2
- JavaScript特性三:this关键字
- jQuery 效果- 动画
- html基础
- javascript 网页跳转的方法
- JQuery 常用方法经典总结
- javaScript 学习笔记
- Maven异常:Plugin execution not covered by lifecycle configuration
- jQuery.extend()方法和jQuery.fn.extend()方法源码分析
- CoffeeScript
- Extjs 2.2中动态隐藏标签的方法
- .NET中JSON数据进行序列化和反序列化
- .NET中JSON数据进行序列化和反序列化
- jQuery插件学习(一)
- xStream完美转换XML、JSON
- JavaScript中字符串截取函数slice()、substring()、substr()
- Node.js Web模块
- HTML img标签之onAbort、onError、onLoad事件与问题