很久没有用过二叉树了,最近由于需要用到了,发现很多知识需要巩固了,中间涉及到一个算法就是找任意两个节点的最近祖先。通过本人回顾和演算,最终提出了下面一个方法,网上也有很多其他的方式实现,再次仅对自己好几个小时的工作作个记录和积累吧! 程序是用C语言写的,个人觉得如果用C#实现会更加方便。
首先是数据结构定义:
typedef char TElemType; typedef bool Status; typedef struct BiTNode{ TElemType data; struct BiTNode * lchild, * rchild; }BiTNode, * BiTree;
其次是建树,用树的定义,以先序序列递归方式建立。
BiTNode * CreateBiTree() { char ch; BiTNode * T; scanf("%c",&ch); if(ch==‘#‘) T = 0; else { T = (BiTree)malloc(sizeof(BiTNode)); T->data = ch; T->lchild = CreateBiTree(); T->rchild = CreateBiTree(); } return T; }
查找最近祖先的基本算法是递归,对每个节点先判断是否有直接关联,都没有就分别获得各自的直系父节点,递归调用时需要通过两个节点的深度来判断下一次调用时用哪个使用父节点。具体实现如下:
//查找两个节点的最近的公共祖先节点 BiTNode * FindNearestAncestor(BiTNode * root, BiTNode* p1, BiTNode* p2, int h1, int h2) { if(!p1 || !p2) return 0; if (p1 == p2) { if (p1 == root) return root; return p1; } if (p1 == p2->lchild || p1 == p2->rchild) return p2; if (p2 == p1->lchild || p2 == p1->rchild) return p1; if (h1 == h2) return FindNearestAncestor( root, GetParent(root, p1), GetParent(root, p2), h1 - 1, h2 - 1); else return FindNearestAncestor( root, h1 > h2 ? GetParent(root, p1) : p1, h1 < h2 ? GetParent(root, p2) : p2, h1 > h2 ? h1 - 1 : h1, h1 < h2 ? h2 - 1 : h2); }
BiTNode * GetParent(BiTNode* root, BiTNode * p) { if(!root || p == root) return 0; if(p == root->lchild || p == root->rchild) { return root; } else { return GetParent(root->lchild, p) == 0 ? GetParent(root->rchild, p) : GetParent(root->lchild, p); } }在主函数中调用如下:
int main() { //测试序列: abc###de##fg### printf("请输入前序序列,空节点用‘#’代替:\n"); BiTree tree = CreateBiTree(); BiTNode * node = FindNearestAncestor( tree, tree->rchild->lchild, tree->rchild->rchild->lchild, GetHeight(tree,tree->rchild->lchild), GetHeight(tree,tree->rchild->rchild->lchild) ); printf("节点%c和节点%c的最近父节点为:%c\n", tree->rchild->lchild->data, tree->rchild->rchild->lchild->data, node->data); return 0; }
//查找节点p的高度,注意与单纯只计算树的高度不同 int GetHeight(BiTNode* root, BiTNode * p, int h = 1) { if (!root) return 0; if (p == root->lchild || p == root->rchild) return h + 1; return GetHeight(root->lchild, p, h+1) == 0 ? GetHeight(root->rchild, p, h+1) : GetHeight(root->lchild, p, h+1); }
abc###de##fg###
对应的二叉树如下:
a
/ \
b d
/ / \
c e f
/
g
结果如下:
仅此记录,供以后忘记了查阅,同时也希望和大家分享。
原文地址:http://blog.csdn.net/u010487568/article/details/24597035