这种建树方法,在学完并查集之后,突然想到的。
利用数组本身一对多的关系,就能完成建树。
先初始化数组,将数组下标值和本身的值相等:
即:father [ 0 ] =0, father [ 1 ] =1,father[ 2 ] =2,father [ 3 ] =3。。。。。father[ N ] =N;
★解释一下为什么说数组本身具有一对多的关系?
比如 father [ 2 ] =2,将father [ 2 ]看成一个箱子,箱子里装着 2 这个数值
———————
/ 2 / |
——————— |
| father[ 2 ] | /
———————
father [ 2 ]这个箱子里,装的数值 ,其实可以是 别的数组, 如1 ,5, 6之类,即father [ 2 ]=1 ,father [ 2 ]=5,father [ 2 ]=6。
但是不能反过来,father [ 1 ] = 2,father [ 5 ] =2,father [ 6 ]=2,因为 father [ i ]中的 i改变,箱子已经变化了。
这就是一数组一对多的关系。即 father [ i ] = x ,i 确定箱子,x决定箱子里的数值。 i 对 x,1对多。
★也就是说关键在于这样的想法,在father [ i ] = x 中,father [ i ]是固定的,而x是灵活可以变的。
建树:
father [ 0 ]【0】
/ / \
father[ 1 ] 【1】 father[ 2 ]【2】 father[ 3 ]【3】
/ | \ \
father [ 4 ]【4】 father [ 5 ]【5】 father [ 6 ]【6】 father[ 7 ]【7】
|
father[ 8 ]【8】
要建这个树,
father[ 0 ] 有三个孩子:father[ 1 ],father[ 2 ],father[ 3 ]
father[ 3 ] 有四个孩子:father[ 4 ],father[ 5 ],father[ 6 ],father[ 7 ]
father[ 5 ] 有一个孩子:father[ 8 ]
首先我们先初始化一个father [ ]数组,将
father [ 1 ] = 0 ; father [ 2 ] = 0 ; father [ 3 ] = 0 ;(实现【 0 】对【 1 】 ,【 2 】,【 3 】的父子关系)
father [ 4 ] = 3 ; father [ 5 ] =
3 ; father [ 6 ] =
3 ;father [ 7 ] = 3 ; (实现【 3 】对【 4 】,【 5 】,【 6 】,【 7 】的父子关系)
father [ 8 ] = 5 ;(实现 【 5 】 对 【 8 】 的父子关系)
★遍历的时候只找到根节点【 8 】 就能倒着 遍历到 【 0 】
father [ 8 ] = 5 ; ------> father [ father [ 8 ] ] = 3 ; -------> father[ father [ father [ 8 ] ] ] =0;
由此可知,这样的缺点在于不能从上而下的遍历,只能从下而上遍历
但确实能将树构建起来,而且非常方便的能从叶子找到它的祖先。
可以继续往下推:
每个结点可以不是简单的数,其实也可以是个结构体数组,只要这个结构体有个编号,正如A [ i ] = x一样的 x这样的编号。
再利用 father[ ]数组,就可以非常方便的 将父子,子与祖宗的关系关联起来,定位编号。