/* 在一棵树中,获取和为某个值的所有路径 比如有树如下 1 / \ 2 3 / \ /\ 5 7 6 7 如果和为10,那么可以得到两个,有两个路径1、2、7和1、3、6 */ /* 标准输入输出头文件 */ #include <iostream> /* 标准库中栈容器头文件 */ #include <stack> using namespace std; /* 树节点结构体 */ typedef struct BiTNode { int nValue; struct BiTNode *pLChild; struct BiTNode *pRChild; }BiTNode, *PBiTree; /* 通过键盘输入,建立树结构,输入时注意先输入根节点, 然后输入左子树,再输入右子树,如果输入0表示子树为空 */ PBiTree Create() { int nValue; PBiTree pRoot; scanf_s("%d", &nValue); // 如果用户输入0,则表示空节点 if (nValue == 0) { pRoot = NULL; } else { // 否则,申请节点内存 pRoot = (PBiTree)malloc(sizeof(BiTNode)); if (NULL == pRoot) { printf("分配内存失败!\n"); } else { // 初始化节点之后,继续输入它的左儿子和右儿子 pRoot->nValue = nValue; printf("请输入%d结点的左子结点:", pRoot->nValue); pRoot->pLChild = Create(); printf("请输入%d结点的右子结点:", pRoot->nValue); pRoot->pRChild = Create(); } } return pRoot; } /* 在这个函数里,实现查找路径 */ void FindSum(PBiTree root,int sum,stack<PBiTree> s) { // 首先判断root是否为NULL,如果是则直接返回了,对于空树,无法做求和工作 if(root==NULL) return; // 将根节点保存到栈中 s.push(root); // 如果该根节点是叶子节点,即左子树和右子树都为空树 if (root->pLChild==NULL&&root->pRChild==NULL) { // 那么判断sum是不是正好等于root保存的value,如果是,那么说明这个路径是满足条件的 if (sum==root->nValue) { // 满足条件则打印栈里的值 while(s.size()!=0) { PBiTree pTemp; pTemp=s.top(); cout<<pTemp->nValue<<" "; s.pop(); } } cout<<endl; } // 如果不是叶子节点,那么则递归的去求满足条件的路径 // 注意这里两个技巧 // 1) 求和的和,在根节点被栈保存之后,在它的子树里,要找的是和为sum-root->nValue的路径 // 2) 栈参数用了普通的参数,而不是引用,在函数调用时,栈被拷贝了,使得每个路径上有各自的栈 if (root->pLChild!=NULL) { FindSum(root->pLChild,sum-root->nValue,s); } if (root->pRChild!=NULL) { FindSum(root->pRChild,sum-root->nValue,s); } } int main() { // 创建树 printf("请输入根结点的值:"); PBiTree pRoot = Create(); cout<<endl; // 输入想得到的和 int sum; cout<<"输入要得到的和:"; cin>>sum; cout<<endl; // 去树中搜索该和的路径,其中s为栈,保存遍历时需要保存的中间节点 stack<PBiTree> s; FindSum(pRoot,sum,s); system("pause"); return 0; }
代码下载地址:http://download.csdn.net/detail/yincheng01/6704519
解压密码:c.itcast.cn
下载代码并解压后,用VC2013打开interview.sln,并设置对应的启动项目后,点击运行即可,具体步骤如下:
1)设置启动项目:右键点击解决方案,在弹出菜单中选择“设置启动项目”
2)在下拉框中选择相应项目,项目名和博客编号一致
3)点击“本地Windows调试器”运行