查找linux 可用节点,二叉树——查找两个任意节点的最近祖先

很久没有用过二叉树了,最近由于需要用到了,发现很多知识需要巩固了,中间涉及到一个算法就是找任意两个节点的最近祖先。通过本人回顾和演算,最终提出了下面一个方法,网上也有很多其他的方式实现,再次仅对自己好几个小时的工作作个记录和积累吧! 程序是用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

结果如下:

561510f267119a95f676e9e8be0b778a.png

仅此记录,供以后忘记了查阅,同时也希望和大家分享。

0b1331709591d260c1c78e86d0c51c18.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值