您的位置:首页 > Web前端

剑指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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: