C++ 二叉树中和为某一值的路径

思路:递归、判断技术条件、采用vector

代码:

/*题目:输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。丛书的根结点开始往下一直到叶节点所经过的节点形成一条路径*/
#include <iostream>
#include <vector>
#include <stdio.h>
#include "BinaryTree.h"
using namespace std;
//to declare
void FindPath(TreeNode* proot, int Sum, vector <int>& path, int& current_sum);
//to initialize
void FindPath(TreeNode* proot, int Sum)
{
	if(proot == NULL)
		return;
	int current_sum =0;
	vector <int> path ;
	FindPath(proot, Sum, path, current_sum);
}
// to recurse
void FindPath
(
	TreeNode* pnode, 
	int Sum,
	vector <int>& path,
	int& current_sum
)
{
	current_sum += pnode -> m_value;
	path.push_back(pnode -> m_value);
	bool is_leaf = pnode -> pLeft ==NULL && pnode ->pRight == NULL;
	if(current_sum == Sum && is_leaf)
	{
		cout<<"Here is a path: ";
		vector<int> :: iterator itr= path.begin();
		while(itr < path.end())
			cout<< *itr++ <<'\t';
		cout <<endl;
	}
	if(pnode -> pLeft != NULL)
		FindPath(pnode -> pLeft ,Sum, path,current_sum);
	if(pnode -> pRight != NULL)
		FindPath(pnode ->pRight , Sum, path,current_sum);
	current_sum -= pnode ->m_value;
	path.pop_back();
}
// ====================测试代码====================
void Test(char* testName, TreeNode* pRoot, int expectedSum)
{
    if(testName != NULL)
        cout<<testName<< " begins"<<endl;

    FindPath(pRoot, expectedSum);
	cout <<endl;
}

//            10
//         /      \
//        5        12
//       /\        
//      4  7     
// 有两条路径上的结点和为22
void Test1()
{
    TreeNode* pNode10 = CreateNode(10);
    TreeNode* pNode5 = CreateNode(5);
    TreeNode* pNode12 = CreateNode(12);
    TreeNode* pNode4 = CreateNode(4);
    TreeNode* pNode7 = CreateNode(7);

    ConnectNodes(pNode10, pNode5, pNode12);
    ConnectNodes(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()
{
    TreeNode* pNode10 = CreateNode(10);
    TreeNode* pNode5 = CreateNode(5);
    TreeNode* pNode12 = CreateNode(12);
    TreeNode* pNode4 = CreateNode(4);
    TreeNode* pNode7 = CreateNode(7);

    ConnectNodes(pNode10, pNode5, pNode12);
    ConnectNodes(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()
{
    TreeNode* pNode5 = CreateNode(5);
    TreeNode* pNode4 = CreateNode(4);
    TreeNode* pNode3 = CreateNode(3);
    TreeNode* pNode2 = CreateNode(2);
    TreeNode* pNode1 = CreateNode(1);

    ConnectNodes(pNode5, pNode4, NULL);
    ConnectNodes(pNode4, pNode3, NULL);
    ConnectNodes(pNode3, pNode2, NULL);
    ConnectNodes(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()
{
    TreeNode* pNode1 = CreateNode(1);
    TreeNode* pNode2 = CreateNode(2);
    TreeNode* pNode3 = CreateNode(3);
    TreeNode* pNode4 = CreateNode(4);
    TreeNode* pNode5 = CreateNode(5);

    ConnectNodes(pNode1, NULL, pNode2);
    ConnectNodes(pNode2, NULL, pNode3);
    ConnectNodes(pNode3, NULL, pNode4);
    ConnectNodes(pNode4, NULL, pNode5);

    printf("No paths should be found in Test4.\n");
    Test("Test4", pNode1, 16);

    DestroyTree(pNode1);
}

// 树中只有1个结点
void Test5()
{
    TreeNode* pNode1 = CreateNode(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()
{
    Test1();
    Test2();
    Test3();
    Test4();
    Test5();
    Test6();
	system("PAUSE");
    return 0;
}
binarytree的相关代码此处省略,可见以前博文
运行结果如下


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值