问题一:输入一棵二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。二叉树结点的定义如下:
struct BinaryTreeNode
{
int m_nValue;
BinaryTreeNode * m_pLeft;
BinaryTreeNode * m_pRight;
};
详细的代码实现:
#include "stdafx.h"
#include "..\Utilities\BinaryTree.h"
#include <vector>
void FindPath(BinaryTreeNode* pRoot, int expectedSum, std::vector<int>& path, int& currentSum);
void FindPath(BinaryTreeNode* pRoot, int expectedSum)
{
if(pRoot == NULL)
return;
std::vector<int> path;
int currentSum = 0;
FindPath(pRoot, expectedSum, path, currentSum);
}
void FindPath
(
BinaryTreeNode* pRoot,
int expectedSum,
std::vector<int>& path,
int& currentSum
)
{
currentSum += pRoot->m_nValue;
path.push_back(pRoot->m_nValue);
// 如果是叶结点,并且路径上结点的和等于输入的值
// 打印出这条路径
bool isLeaf = pRoot->m_pLeft == NULL && pRoot->m_pRight == NULL;
if(currentSum == expectedSum && isLeaf)
{
printf("A path is found: ");
std::vector<int>::iterator iter = path.begin();
for(; iter != path.end(); ++ iter)
printf("%d\t", *iter);
printf("\n");
}
// 如果不是叶结点,则遍历它的子结点
if(pRoot->m_pLeft != NULL)
FindPath(pRoot->m_pLeft, expectedSum, path, currentSum);
if(pRoot->m_pRight != NULL)
FindPath(pRoot->m_pRight, expectedSum, path, currentSum);
// 在返回到父结点之前,在路径上删除当前结点,
// 并在currentSum中减去当前结点的值
currentSum -= pRoot->m_nValue;
path.pop_back();
}
// ====================测试代码====================
void Test(char* testName, BinaryTreeNode* pRoot, int expectedSum)
{
if(testName != NULL)
printf("%s begins:\n", testName);
FindPath(pRoot, expectedSum);
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 _tmain(int argc, _TCHAR* argv[])
{
Test1();
Test2();
Test3();
Test4();
Test5();
Test6();
return 0;
}
输出结果如下;
扩展:二叉搜索树的后序遍历
详细的代码实现:
#include "stdafx.h"
// BST:Binary Search Tree,二叉搜索树
bool VerifySquenceOfBST(int sequence[], int length)
{
if(sequence == NULL || length <= 0)
return false;
int root = sequence[length - 1];
// 在二叉搜索树中左子树的结点小于根结点
int i = 0;
for(; i < length - 1; ++ i)
{
if(sequence[i] > root)
break;
}
// 在二叉搜索树中右子树的结点大于根结点
int j = i;
for(; j < length - 1; ++ j)
{
if(sequence[j] < root)
return false;
}
// 判断左子树是不是二叉搜索树
bool left = true;
if(i > 0)
left = VerifySquenceOfBST(sequence, i);
// 判断右子树是不是二叉搜索树
bool right = true;
if(i < length - 1)
right = VerifySquenceOfBST(sequence + i, length - i - 1);
return (left && right);
}
// ====================测试代码====================
void Test(char* testName, int sequence[], int length, bool expected)
{
if(testName != NULL)
printf("%s begins: ", testName);
if(VerifySquenceOfBST(sequence, length) == expected)
printf("passed.\n");
else
printf("failed.\n");
}
// 10
// / \
// 6 14
// /\ /\
// 4 8 12 16
void Test1()
{
int data[] = {4, 8, 6, 12, 16, 14, 10};
Test("Test1", data, sizeof(data)/sizeof(int), true);
}
// 5
// / \
// 4 7
// /
// 6
void Test2()
{
int data[] = {4, 6, 7, 5};
Test("Test2", data, sizeof(data)/sizeof(int), true);
}
// 5
// /
// 4
// /
// 3
// /
// 2
// /
// 1
void Test3()
{
int data[] = {1, 2, 3, 4, 5};
Test("Test3", data, sizeof(data)/sizeof(int), true);
}
// 1
// \
// 2
// \
// 3
// \
// 4
// \
// 5
void Test4()
{
int data[] = {5, 4, 3, 2, 1};
Test("Test4", data, sizeof(data)/sizeof(int), true);
}
// 树中只有1个结点
void Test5()
{
int data[] = {5};
Test("Test5", data, sizeof(data)/sizeof(int), true);
}
void Test6()
{
int data[] = {7, 4, 6, 5};
Test("Test6", data, sizeof(data)/sizeof(int), false);
}
void Test7()
{
int data[] = {4, 6, 12, 8, 16, 14, 10};
Test("Test7", data, sizeof(data)/sizeof(int), false);
}
void Test8()
{
Test("Test8", NULL, 0, false);
}
int _tmain(int argc, _TCHAR* argv[])
{
Test1();
Test2();
Test3();
Test4();
Test5();
Test6();
Test7();
Test8();
return 0;
}