结合过8楼和11楼的说法明白题目意思了~就是说寻找树的两个子节点的最近父节点~因为通常二叉树每个节点都只有一个入口~回溯搜索时就只有一条路径~所以正常算法的时间复杂度应该为0(n)而不是0(n^2)~是多项式的NP问题~时间复杂度为0(n)的算法有很多~~
第一种就是8楼所说的算法~实现起来最简单~就是记录遍历节点状态~在这里我就先不说了~和下面三种算法时间复杂度同是0(n)~不过还是有一点差距的~差了个常量级~具体会在下面总结~
第二种就是逆树~~另外建立一颗树~不过建立该树的指针是倒过来的~性质有点类似于栈~~记录该节点有没有遍历过~如果没有就在该节点上建立一个栈的节点~~
不过这样建立时就要用一个数组指针来记录根节点来作为入口这样搜索就方便了~
这种逆树搜索实现难度感觉还是有一定的~主要用于广搜时要找到并打印出最小权值的一种状态(所以这有时就是广搜纠结的地方~打印状态数据会是逆序的~所以链表逆序算法就有所应用了)~~~
第三种就是用带指针标记的广搜(实质同第一种差不多~不过就是方法上变化了点)~就是用结构体(元素至少包含两个~一个储存值和一个链表指针~还可以加储存节点下标和搜索深度)队列保存数据(注意出队时不要将元素真正删除~直接移动队头指针就行了~也就是所谓的"假出队"~后面打印输出数据可能要用到)~~然后队尾用一个指针指向队头~遍历完毕检查方法和第一种是一样的~~实质两种方法的储存结构可以等效~不同的是第一种方法是深度游优先搜索~第二种方法是广度优先搜索~~
第四种就是用邻接矩阵或者邻接表标记图的状态~不过矩阵或表所储存建立图的方向是逆序的~其实和上面两种方法实质一样~
前面三种的空间复杂度都是0(n)第四种矩阵的话是0(n^2)邻接表则是0(n)~解释一下原题的二叉树结构逆序后每个顶点就那么一个入口所以表的空间复杂度是0(n)~前四种适用于对已知两个节点的一次搜索~~如果要进行多次比较的话寻找就要从新搜索了~~所以就有了第五种搜索方案
该方案其实就是对前四搜索方案的一种改进~~~
其实算法思想就是floyd算法~~~
计算其共同祖先时可以用按搜索深度进行回溯比对~~
该算法的空间复杂度是0(n^2)时间复杂度和树的相对高度有关~最好是0(n*log(n))~此时该树是完全二叉树~最差是(n^2)~此时该树是程线性结构~
总结一下~
第一种是用树结构求解~
第二种是用栈结构深度搜索求解~
第三种是用队列结构和栈结构广度搜索求解~
第四种是用图的储存结构求解~
第五种是求解任意两个节点之间的~
看上去第一种实现最为方便~但事实上每一次搜索的执行操作是一样的~就算直接给出p和q的地址也不能直接把那个地址为入口~具体原因是存在方向可逆性问题~
第二种和第三种一个是深度搜索~一个是广度搜索~但只是建立数据结构的过程不同~建立后的结构实质是一样的~虽然实现起来比第一种要复杂~但是可以以该地址作为入口沿一条路径回到根节点~第四种也和第二第三种差不多~就是储存数据方式和前两种有些出入~邻接矩阵或者邻接表储存结构每一个节点之间是离散关系~其实没必要去真正建立一张图~因为那图原型就是原题给出的树~遍历该树的过程已经能获取矩阵或表的数据~通过矩阵或表就可以求解了~如果直接用矩阵或表来计算则执行效率和第一种差不多~细化的话如果是矩阵则执行效率还会高一些(上面提及过树逆序后每个节点就那么一个出口~其实用表的话可以用一个一标记其出口的一维数组取代就行了)~第五种适用于多次对于任意两个节点的搜索~生成二维表后每次搜索直接查表就行了~不过消耗空间较大和建表时间较长时肯定的~
至于如何选择就个人决定了~~
[此贴子已经被作者于2017-4-24 20:53编辑过]