1 /*
2 * SearchBTreePath.cpp
3 *
4 当访问到某一结点时,把该结点添加到路径上,并累加当前结点的值。
5 如果当前结点为叶结点并且当前路径的和刚好等于输入的整数,则当前的路径符合要求,我们把它打印出来。
6
7 如果当前结点不是叶结点,则继续访问它的子结点。当前结点访问结束后,递归函数将自动回到父结点。
8 因此我们在函数退出之前要在路径上删除当前结点并减去当前结点的值,
9 以确保返回父结点时路径刚好是根结点到父结点的路径。
10
11 我们不难看出保存路径的数据结构实际上是一个栈结构,因为路径要与递归调用状态一致,
12 而递归调用本质就是一个压栈和出栈的过程。
13 */
14
15 //Method 1:
16
17 #define NULL 0
18
19 using namespace std;
20 #include <iostream>
21 #include <stdio.h>
22
23 #include <vector>
24
25 struct BinaryTreeNode // a node in the binary tree
26 {
27 int m_nValue; // value of node
28 BinaryTreeNode *m_pLeft; // left child of node
29 BinaryTreeNode *m_pRight; // right child of node
30 };
31
32 //打印路径
33 void printPath(BinaryTreeNode *path);
34 /**
35 *sum为要求的整数和
36 *curSum为从根节点到tree父节点,路径上所有数的和
37 *path指向当前路径的最后一个节点,该路径有BinaryTreeNode组成双向链表
38 *m_pRight指向路径下一节点,m_pLeft指向上一节点
39 **/
40
41
42 void searchPath(BinaryTreeNode *tree,BinaryTreeNode *path,int curSum,int sum)
43 {
44 curSum += tree->m_nValue;
45 //路径值已经大于所求和,返回
46 if(curSum>sum)
47 return;
48
49
50 BinaryTreeNode *node=new BinaryTreeNode();
51 node->m_nValue=tree->m_nValue;
52 //将当前节点的值加入到路径中
53 if(path==NULL)
54 path=node;
55 else
56 {
57 path->m_pRight=node;
58 node->m_pLeft=path;
59 path=node;
60 }
61
62 if(curSum==sum)
63 {
64 //路径结束且和=sum,为所求
65 if(tree->m_pLeft==NULL&&tree->m_pRight==NULL)
66 {
67 //获得路径头节点,用于打印
68 while(path->m_pLeft)
69 path=path->m_pLeft;
70 printPath(path);
71 }
72 //若当前路径的和=sum,但路径还未到达叶节点,此路径不可行
73 delete node;
74 return;
75 }
76
77 //curSum<sum,继续搜寻路径
78 if(tree->m_pLeft!=NULL)
79 searchPath(tree->m_pLeft,path,curSum,sum);
80
81 if(tree->m_pRight!=NULL)
82 searchPath(tree->m_pRight,path,curSum,sum);
83 delete node;
84 }
85 void printPath(BinaryTreeNode *path)
86 {
87 while(path)
88 {
89 cout<<path->m_nValue<<"";
90 path=path->m_pRight;
91 }
92 cout<<endl;
93 }
94
95
96 int main()
97 {
98 BinaryTreeNode *root=NULL;
99
100 BinaryTreeNode node10;
101 node10.m_nValue=10;
102 BinaryTreeNode node5;
103 node5.m_nValue=5;
104 BinaryTreeNode node12;
105 node12.m_nValue=12;
106
107 BinaryTreeNode node4;
108 node4.m_nValue=4;
109
110 BinaryTreeNode node7;
111 node7.m_nValue=7;
112
113 node10.m_pLeft=&node5;
114 node10.m_pRight=&node12;
115 node5.m_pLeft=&node4;
116 node5.m_pRight=&node7;
117
118 node12.m_pLeft=node12.m_pRight=NULL;
119 node4.m_pLeft=node4.m_pRight=NULL;
120 node7.m_pLeft=node7.m_pRight=NULL;
121
122 root=&node10;
123
124 BinaryTreeNode *path=NULL;
125 cout<<"搜寻值为22的路径有如下几条:"<<endl;
126 searchPath(root,path,0,22);
127
128 cin.get();
129 }
130
131
132
133 //Method 2: This is a excellent program.
134
135 #include <iostream>
136 #include <vector>
137 #include <stdlib.h>
138
139 using namespace std;
140
141 struct BinaryTreeNode{ int m_nValue;
142 BinaryTreeNode * m_pLeft;
143 BinaryTreeNode * m_pRight;
144 };
145
146 int count = 0;
147
148 void findPath(BinaryTreeNode *pTreeNode,
149 int expectedSum,
150 vector<int>& path,
151 int& currentSum)
152 {
153 if( !pTreeNode )
154 return;
155 //结点值添加至当前和变量中
156 //结点压入栈中
157 currentSum += pTreeNode->m_nValue;
158 path.push_back(pTreeNode->m_nValue);
159 bool isLeaf = !(pTreeNode->m_pLeft) && !(pTreeNode->m_pRight);
160 //当前结点为叶子结点,且和为期望值,打印路径
161 if(currentSum == expectedSum && isLeaf)
162 {
163 vector<int>::iterator iter;
164 for(iter = path.begin(); iter != path.end(); iter++)
165 {
166 cout << *iter << "\t";
167 }
168 cout << endl;
169 }
170 //当前结点不为叶子结点,查找它的左右孩子结点
171 if(pTreeNode->m_pLeft)
172 findPath(pTreeNode->m_pLeft, expectedSum, path, currentSum);
173 if(pTreeNode->m_pRight)
174 findPath(pTreeNode->m_pRight, expectedSum, path, currentSum);
175 //当前结点删除,退至其父结点
176 currentSum -= pTreeNode->m_nValue;
177 path.pop_back();
178 }
179
180 void addTree(BinaryTreeNode **T, int num)
181 {
182 if(*T == NULL)
183 {
184 *T = (BinaryTreeNode *)malloc(sizeof(BinaryTreeNode));
185 (*T)->m_nValue = num;
186 (*T)->m_pLeft = NULL;
187 (*T)->m_pRight = NULL;
188 }
189 else if((*T)->m_nValue > num)
190 addTree(&((*T)->m_pLeft), num);
191 else if((*T)->m_nValue < num)
192 addTree(&((*T)->m_pRight), num);
193 else
194 cout << "重复加入同一结点" << endl;
195 }
196
197 int main()
198 {
199 BinaryTreeNode * T = NULL;
200 addTree(&T, 10);
201 addTree(&T, 12);
202 addTree(&T, 5);
203 addTree(&T, 7);
204 addTree(&T, 4);
205
206 vector<int> path;
207 int sum = 0;
208 findPath(T, 22, path, sum);
209 return 0;
210 }