二叉树——查找两个任意节点的最近祖先
2014-04-27 18:55
477 查看
很久没有用过二叉树了,最近由于需要用到了,发现很多知识需要巩固了,中间涉及到一个算法就是找任意两个节点的最近祖先。通过本人回顾和演算,最终提出了下面一个方法,网上也有很多其他的方式实现,再次仅对自己好几个小时的工作作个记录和积累吧! 程序是用C语言写的,个人觉得如果用C#实现会更加方便。
首先是数据结构定义:
其次是建树,用树的定义,以先序序列递归方式建立。
空节点的分隔符本处使用的是“#”,可以用其他字符替代。
查找最近祖先的基本算法是递归,对每个节点先判断是否有直接关联,都没有就分别获得各自的直系父节点,递归调用时需要通过两个节点的深度来判断下一次调用时用哪个使用父节点。具体实现如下:
其中GetParent是获取以root为树根的树中p节点的直系父节点,定义如下:
上述使用了GetHeight函数,用来获取给定树中节点p的高度,这个函数的实现耗费了较多时间,主要是以前都是获取树的高度,很少获取指定节点的高度,其实现如下:
上述测试使用的先序序列为
abc###de##fg###
对应的二叉树如下:
a
/ \
b d
/ / \
c e f
/
g
结果如下:
仅此记录,供以后忘记了查阅,同时也希望和大家分享。
首先是数据结构定义:
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); }
其中GetParent是获取以root为树根的树中p节点的直系父节点,定义如下:
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; }
上述使用了GetHeight函数,用来获取给定树中节点p的高度,这个函数的实现耗费了较多时间,主要是以前都是获取树的高度,很少获取指定节点的高度,其实现如下:
//查找节点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
结果如下:
仅此记录,供以后忘记了查阅,同时也希望和大家分享。
相关文章推荐
- 二叉树——查找两个任意节点的最近祖先
- LCA问题:求二叉树中任意两个节点的最近公共祖先
- 在二叉树中查找两个节点的最近的公共祖先节点(有回溯指针)(NCA--nearest common ancestor)
- 查找二叉树某两个节点最近的共同祖先及改进方法
- 二叉树——查找两个随机节点最近的祖先
- 在二叉树中,求任意两个节点的最近公共祖先(遍历的应用算法)
- 在二叉树中查找两个节点的最近的公共祖先节点(无回溯指针)(NCA--nearest common ancestor)
- 二叉树中任意两个节点的最近公共祖先节点
- 二叉树(12)----查找两个节点最低祖先节点(或最近公共父节点等),递归和非递归
- 求二叉树的任意两个节点的最近公共祖先
- 二叉树中两个节点的最近公共祖先节点
- 寻找二叉树中两个节点的最近祖先
- 二叉树中两个节点的最近祖先节点
- 寻找二叉树中两个节点的最近的公共祖先
- 【学习点滴-数据结构-二叉树】求二叉树中某两个节点的最近公共祖先
- [转] 寻找二叉树中两个节点的最近的公共祖先
- 二叉树中两个节点的最近公共祖先节点
- 二叉树两个节点求最近的公共祖先节点java代码实现
- 求二叉树任意两个结点最近的共同祖先
- 二叉树中两个节点的最近公共祖先节点方法全集