二叉树——查找两个随机节点最近的祖先
2015-12-14 21:24
585 查看
非常实用的太久没有一个二叉树,因为需要使用最近,我们觉得非常有必要巩固知识。中间涉及到一个随机算法是寻找两个节点的直接祖先。
我记得和牙石通过,于提出了以下一个方法,网上也有非常多其它的方式实现,再次仅对自己好几个小时的工作作个记录和积累吧!
程序是用C语言写的,个人认为假设用C#实现会更加方便。
首先是数据结构定义:
其次是建树。用树的定义,以先序序列递归方式建立。
空节点的分隔符本处使用的是“#”,能够用其它字符替代。
查找近期祖先的基本算法是递归。对每一个节点先推断是否有直接关联。都没有就分别获得各自的直系父节点,递归调用时须要通过两个节点的深度来推断下一次调用时用哪个使用父节点。
详细实现例如以下:
当中GetParent是获取以root为树根的树中p节点的直系父节点,定义例如以下:
上述使用了GetHeight函数。用来获取给定树中节点p的高度,这个函数的实现耗费了较多时间。主要是曾经都是获取树的高度,非常少获取指定节点的高度,事实上现例如以下:
上述測试使用的先序序列为
abc###de##fg###
相应的二叉树例如以下:
a
/ \
b d
/ / \
c e f
/
g
结果例如以下:
只有这个纪录。现在,忘记之后。同时也想和大家分享。
我记得和牙石通过,于提出了以下一个方法,网上也有非常多其它的方式实现,再次仅对自己好几个小时的工作作个记录和积累吧!
程序是用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); }
当中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
结果例如以下:
只有这个纪录。现在,忘记之后。同时也想和大家分享。
相关文章推荐
- 去除标题栏和全屏的方法
- 团队作业--Beta版本冲刺
- Nginx基本命令
- 数据结构C++语言实现——图
- Spring中ApplicationContext对事件传递
- 110 Balanced Binary Tree
- I NEED A OFFER! 动态规划 01 背包
- android.content.res.Resources$NotFoundException:
- 【NCRE】——Winform窗体控件随窗体大小而变化
- 网络请求 同步get 同步post 异步get 异步post
- 最小生成树(题解) 两种解法
- Test,test
- 上Https 和 http 差分
- 编译kernel:编译 配置项
- Linux-CentOS XAMPP Apache mod_xsendfile 为php提供更快的文件下载
- 基于Eclipse的Hadoop应用开发环境配置和范例
- 1452: [JSOI2009]Count
- HDU 1060 求N^N的最高位 (数学,科学计数法+log10()函数)
- 搜索二维矩阵——LintCode
- Beta版本冲刺———第六天