点:深度遍历运用
题意:如一个二叉树,求和为某节点值的全部路径。
剑指offer面试题25
思路:深度遍历中的前序遍历是先拿当前节点值,再接着遍历,显然这个是适合本题需求的
题意要求能打印出全部的路径,这需要遍历过程中,能知道之前已经走过的路径,也就是需要将过往路径也递归入栈,
所以,走前序遍历,入栈的除了当前的节点,还包括当前已经累加的和,当前走过的路径,当然还需要那个和,然后累加当前节点值到当前和,比较是否已经符合,已经符合就打印输出当前走过的路径再加当前节点即可。
当前和、当前走过的路径我以queue,均按值传递的递归入栈,这样代码非常简单。
代码:
#include <iostream>
#include <queue>
template<class T> struct Node {
Node<T> *left;
Node<T> *right;
T val;
Node(T _val):val(_val), left(nullptr), right(nullptr){}
};
template<class T> class Btree {
Node<T> *root;
public:
Btree():root(nullptr) {}
void Free (Node<T> *cur) {
if (cur) {
Free(cur->left);
Free(cur->right);
delete cur;
cur = nullptr;
}
}
~Btree() {
Free(root);
}
void Add (T val) {
if (!root) {
root = new Node<T>(val);
return;
}
Node<T> *cur = root;
while (cur) {
if (cur->val > val) {
if (!cur->left) {
Node<T> *newnode = new Node<T>(val);
cur->left = newnode;
break;
} else {
cur = cur->left;
}
} else if (cur->val < val) {
if (!cur->right) {
Node<T> *newnode = new Node<T>(val);
cur->right = newnode;
break;
} else {
cur = cur->right;
}
} else {
break;
}
}
}
void Find (Node<T> *cur, std::queue<Node<T> *> q, int cnt, const int sum) {
if (cur) {
q.push(cur);
if (cur->val + cnt == sum) {
std::queue<Node<T> *> t;
while (!q.empty()) {
t.push(q.front());
std::cout << q.front()->val << "\t";
q.pop();
}
std::cout << std::endl;
while (!t.empty()) {
q.push(t.front());
t.pop();
}
}
cnt += cur->val;
Find(cur->left, q, cnt, sum);
Find(cur->right, q, cnt, sum);
}
}
void Findpath (const int sum) {
int cnt = 0;
std::queue<Node<T> *> q;
Find(root, q, cnt, sum);
}
};
int main () {
Btree<int> bt;
bt.Add(10);
bt.Add(7);
bt.Add(5);
bt.Add(0);
bt.Add(9);
bt.Add(8);
bt.Add(12);
bt.Add(11);
bt.Add(20);
bt.Add(13);
bt.Add(15);
bt.Add(25);
bt.Add(22);
bt.Add(28);
int sum = 22;
bt.Findpath(sum);
return 0;
}