免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 4468 | 回复: 11
打印 上一主题 下一主题

请教二叉树的比较算法 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-12-26 10:06 |只看该作者 |倒序浏览
是这样的,现在我这里有两棵建立好的二叉树,同时也能够解析开(指的是,各结点间的关联)
两棵树有相同的地方,也有差异,简单的一种情况为:
    A            A
  |    |         |    |
C      D      C   |  |
                  B  D
这是比较简单的情况了(当然,一切从简单入手)
我如何才能对其进行比较,最终应该是能够达到合并,而画树,有清晰直观的效果
假设右边树可以标记为A' C' B' D'
到时候合并到左边,预期效果如下:
    AA'
  |       |
CC'     |   |
      B'    DD'
也不知道这种思路行不行,感觉上很痛苦
大家有什么其他思路没
或者实现这种方法,觉得容易的算法

我在找关系的时候,必须层层向上寻找同样的父亲产生关联,数据的结构感觉也很很复杂


更新内容:
现在我把实际上,预期能够比较的两棵样品树贴上来
如果各位高人,谁在空闲的时候,不妨帮我想想办法,如何实现合并和比较
十分感谢了



[ 本帖最后由 perljoker 于 2008-1-4 13:14 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2007-12-26 10:31 |只看该作者

  1. 考虑到你的数据处理, 可以用key为路茎的hash来保存下面的树:
  2.        A
  3.    |       |
  4.    C    |     |
  5.         B     D

  6. A   => 'A'
  7. AL  => 'C'
  8. ARL => 'B'
  9. ARR => 'D'

  10. 或者给你现有的树的每个节点增加一个这样的field, 那么合并就很简单了, 格式化输出也很容易.
复制代码

论坛徽章:
0
3 [报告]
发表于 2007-12-26 10:42 |只看该作者
原帖由 Lonki 于 2007-12-26 10:31 发表

考虑到你的数据处理, 可以用key为路茎的hash来保存下面的树:
       A
   |       |
   C    |     |
        B     D

A   => 'A'
AL  => 'C'
ARL => 'B'
ARR => 'D'

或者给你现有的树的每个节点 ...

谢谢Lonki,但是我觉得无法实现合并啊
如我给的例子
左边 AR=D,右边 ARR=D
如果要合并,这个需要被认为是同一个东西,就是都是D
(这里还存在一个树的再排序……原树BD可能位置还不同……,这个另外说)

而且如上,AR是空的,也就是需要其他东西来识别,这是个问题

论坛徽章:
0
4 [报告]
发表于 2007-12-26 11:20 |只看该作者
补充下: 所有节点都要记录. 假定根节点以外的非叶子节点用'#'记:
       A
   |       |
   C    |     |
        B     D

A   => 'A'
AL  => 'C'
AR  => '#'
ARL => 'B'
ARR => 'D'

将2个hash的item都添加到新hash, 遇到相同key时:
若任意一方为#, 则为#, 否则字符串合并

论坛徽章:
0
5 [报告]
发表于 2007-12-26 16:32 |只看该作者
这样确实能处理一者父结点是另一个子结点的问题
如果出现不同结点,我需要根据一定规则多开一个叉
用这种方法前,我得去给树重新排下序

继续……

论坛徽章:
0
6 [报告]
发表于 2007-12-26 16:42 |只看该作者
有现成的模块。

论坛徽章:
0
7 [报告]
发表于 2007-12-26 18:01 |只看该作者
原帖由 perljoker 于 2007-12-26 16:32 发表
这样确实能处理一者父结点是另一个子结点的问题
如果出现不同结点,我需要根据一定规则多开一个叉
用这种方法前,我得去给树重新排下序

继续……


举个例子呢?

论坛徽章:
0
8 [报告]
发表于 2007-12-27 16:46 |只看该作者
原帖由 Lonki 于 2007-12-26 18:01 发表


举个例子呢?

发现排序更恐怖,我这树太不规矩了

是这样的,假如通过#覆盖下面叶结点,是该用在该叶结点可能出现在另一棵树的子结点里面才可以
否则就会丢失信息,是这样理解的吧
假如C是tree_one的LL特有,D是tree_two的LL特有,这时候需要一定规则提高深度的吧

实际上的树则是,乱序(就我们看来乱序,建树的时候方法比较复杂),而且几乎无法对应
比如这边LL是C,那边LL可能是D,或者父结点,左右次序无法对应,结点差异很大

现在的想法是评分制度,首先将所有叶子全部存贮一次,并且相同的名字(如左树的D和右树的D)划分小组
两棵树的某一个结点如果相对应,再次划分小组存储(方法是,查看子结点是否对应,比如这边AB,那边是否A'B',假如是根结点,那就好多层比较了……)
如此层层向上,直到最后只剩下一个小组(过程感觉就很恐怖,存储提取方式,让我也觉得难下手)

论坛徽章:
0
9 [报告]
发表于 2007-12-27 18:00 |只看该作者
# 迷惑, 之前的理解是仅仅按照层次合并.
#
# 对于如下左右2树:
#          A                     A'
#      |       |             |       |
#    |       |             |   |   |   |
#    C       B             D'  E'  B'  F'
#
# 我之前的理解是合并为下面的树:
#          AA'
#     |          |
#  |     |    |     |
# CD'    E'  BB'    F'
#
# 你的合并结果应该是什么?

论坛徽章:
0
10 [报告]
发表于 2007-12-28 09:27 |只看该作者
只有相同的才可以合并,比如BB',合并以后看作一个B也一样
C的位置在这里就很难说了
相当于要从一个表里面去查他的优先度(这里就是指分叉的优先度)
然后,决定在哪里,比如在B'F'上面分叉,或者和B分叉,或者在D'E'上分叉,或者与D'或者E'分叉
根据表里面先后顺序决定
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP