#include <iostream> #include <vector> #include <algorithm> using namespace std; class Node { public: int c; Node *left, *right; Node(): c(0), left(0), right(0) {} Node(int i, Node *l, Node *r): c(i), left(l), right(r) {} }; class WrapNode { public: Node *n; int visit_times; WrapNode():n(0), visit_times(0) {} WrapNode(Node *nn, int i):n(nn), visit_times(i) {} }; void Maketree(Node &n) { Node *p2 = new Node(2, 0, 0); Node *p3 = new Node(3, 0, 0); Node *p4 = new Node(4, 0, 0); Node *p5 = new Node(5, 0, 0); Node *p6 = new Node(6, 0, 0); Node *p7 = new Node(7, 0, 0); Node *p8 = new Node(8, 0, 0); Node *p9 = new Node(9, 0, 0); p5->left = p8; p5->right = p9; p2->left = p4; p2->right = p5; p3->left = p6; p3->right = p7; n.left = p2; n.right = p3; } //该函数中栈会保存从根节点到当前正访问节点的完整路径。 //当某节点被访问超过2次时就从栈中删除该节点 //第一次被访问时计数, 左子树访问完时该元素在栈顶,增加计数: =2开始访问右子树, //右子树访问完时该元素仍然在栈顶, 再累加计数于是超过2, 直接退栈 //该函数每次调用会得到两个数组, 顺序比较两个数组得到最后一个相同的元素即可 //动手之前需要彻底想清楚, 靠调试不能很好的解决问题, 耗时近2个小时。。。。 void find_nearest_parent(Node &n, int i, int j) { std::vector<WrapNode> pv; Node *p = &n; cout <<"i: " << i <<", j: " << j << endl; while(p || !pv.empty()) { if(p) { pv.push_back(WrapNode(p, 1)); if(p->c == i || p->c == j) { for(int k = 0; k < pv.size(); k++) cout << pv[k].n->c <<"(" <<pv[k].visit_times <<")/t"; cout << endl; } p = p->left; } else { while(!p && !pv.empty()) { if(++pv[pv.size() - 1].visit_times > 2) //已经访问完右子树 pv.pop_back(); else { p = pv[pv.size() - 1].n; //继续访问右子树 p = p->right; } } } } return; } int _tmain(int argc, _TCHAR* argv[]) { Node n; n.c = 1; Maketree(n); find_nearest_parent(n, 3, 5); find_nearest_parent(n, 8, 6); find_nearest_parent(n, 8, 7); find_nearest_parent(n, 4, 3); find_nearest_parent(n, 4, 2); find_nearest_parent(n, 5, 2); find_nearest_parent(n, 4, 5); find_nearest_parent(n, 5, 3); find_nearest_parent(n, 2, 3); find_nearest_parent(n, 6, 7); return 0; } ==================================================================== 递归版本,只用了10分钟。。。 static int a[30]; int len = 0; void find_nearest_parentp(Node *n, int i, int j) { if(n == 0) { return; } a[len++] = n->c; if(i == n->c || j == n->c) { for(int k = 0; k < len; k++) cout << a[k] <<"/t"; cout << endl; } find_nearest_parentp(n->left, i, j); find_nearest_parentp(n->right, i, j); --len; }