2024王道408数据结构 P129 T5
思考过程
- 首先看题目,给了我们编号i和j的两个结点,并且告诉我们这个二叉树按顺序存储结构进行存储,让我们去找这两个结点的最近的公共祖先结点的值。
- 假设我们的二叉树长这个样子
将这些值存在一个一维数组里。我们为了方便让下标从1开始,接下来给这些值进行编号,编号也就是他们的下标。
注意这些空缺的位置在一维数组里也是要存储的,在数组里就让他们的值为-1或者0,具体表现为以下这个样子,上面那一行蓝色的数字就是他们的下标。用顺序存储就已经存储好了。
3. 题目给了我们I和j结点,那我们首先要保证I和j均存在,
Tree[i]和Tree[j]都不等于-1
如果等于-1了那就说明这个结点是不存在的。他们俩存在的话就开始遍历,当i=j时就表示他们已经遍历到最近的公共祖先结点了,返回return Tree.data[i]
,当i > j时说明要找i的父结点,直接i=i/2就行能往上找了,当i < j时也一样让j=j/2,每一次判断都让一个结点找他的父结点,这样下去i和j肯定会相遇的,相遇就说明找到了公共祖先结点。
举个例子
- 现在当i等于10,j等于7时,
要找他们的公共祖先结点,先判断I和j是否存在,当I和j都存在时就可以进入循环了,此时i>j,就让i去找他此时的父结点,i/2等于5,j不动
这样就让I找到了他的父结点。
- 然后再开始判断I<j,此时让j去找他的父结点,j/2等于3,这样一直往上找就能找到他们的公共祖先结点,在这个例子里也就是1。
代码过程
都讲到这里了相信应该能写出代码了吧,首先判断i和j是否存在if (Tree.data[i] != -1 && Tree.data[j] != -1)
当i和j存在时进入循环while(i != j)
当i==j时就说明已经找到公共祖先结点,进入循环后判断if(i > j) i = i/2;
相同j也是if (i < j) j = j/2;
最后return结果。
完整代码如下
//
// Created by 黎圣 on 2023/8/8.
//
#include "iostream"
using namespace std;
struct Tree
{
//这是我举的例子
int data[12] = {-1,1,2,3,-1,4,-1,5,-1,-1,6,-1};
};
int Common(Tree t, int i ,int j)
{
if (t.data[i] != -1 && t.data[j] != -1)
{
while (i != j)
{
if (i > j)
i = i / 2;
else if (i < j)
j = j / 2;
}
return t.data[i];
}
else
return -1;
}
int main()
{
Tree t;
int res = Common(t, 7, 10);
printf("%d", res);
return 0;
}
这是我写的第一道二叉树的题,所以也讲的比较详细,同时也说给我自己听,最后感谢b站up主@吸血小金鱼