二叉树的最近公共祖先LCA

news/2024/11/26 2:41:15/

一、什么是最近公共祖先

LCA为最近公共祖先(Lowest Common Ancestor)的缩写。
对于一棵有根树T的两个节点u,v,最近公共祖先LCA(T,u,v)代表一个节点x。
在这里插入图片描述
LCA(5,6) = 2
LCA(7,12) = 3
LCA(2,1)=1

二、公共祖先的朴素解法

  1. 两个节点先调整到相同的深度
  2. 每一次两个点同时向上跳一层,当两个点相遇即为所求两点的LCA.
    对于一组询问,时间复杂度为O(N)

在这里插入图片描述
需要深度遍历,然后构造出这么一张表

在这里插入图片描述
假设求LCA(D,G)
第一步:先判断D的深度为3,G的深度为1
第二步:将D根据父节点数组,往上走一步,也就是节点B,
第三步:此时深度B为2和1还是不同,需要继续往上,也就是A,此时 A,G的深度一致
第四步:判读A的父节点和G的父节点是否一致,如果一致则找到,不一致则同时上调一步,如此循环直到两者父节点首次相同。

三、递归解法

有以下图

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

四、代码

以下代码,构建了如下的一颗树,并分别实现了朴素法和递归法

在这里插入图片描述

#include<iostream>
using namespace std;
using ElemType = char;typedef struct BiTNode
{ElemType data;int nIndex;struct BiTNode* lchild;struct BiTNode* rchild;}BiTNode, * BiTree;int arrayD[100] = { -1 };
int arrayF[100] = { -1 };
void DFS(BiTNode* tree, int nd, int nf)
{if (tree){DFS(tree->lchild, nd + 1, tree->nIndex);arrayD[tree->nIndex] = nd;arrayF[tree->nIndex] = nf;DFS(tree->rchild, nd + 1, tree->nIndex);}
}int LCA1(int u, int v)
{if (arrayD[u] < arrayD[v]){swap(u, v);}if (arrayD[u] > arrayD[v] && arrayF[u] != v){while (arrayD[u] != arrayD[v]){u = arrayF[u];}while (arrayF[u] != arrayF[v]){u = arrayF[u];v = arrayF[v];}}return arrayF[u];}BiTNode* LCA2(BiTNode *pRoot,BiTNode *p,BiTNode *q)
{if (pRoot == p|| pRoot == q || pRoot == NULL){return pRoot;}BiTNode* pLeft = LCA2(pRoot->lchild, p, q);BiTNode* pRight = LCA2(pRoot->rchild, p, q);if (pLeft && pRight){return pRoot;}else if (pLeft){return pLeft;}else if (pRight){return pRight;}else{return NULL;}
}int main()
{BiTNode b1, b2, b3, b4, b5, b6, b7;memset(&b1, 0, sizeof(BiTNode));memset(&b2, 0, sizeof(BiTNode));memset(&b3, 0, sizeof(BiTNode));memset(&b4, 0, sizeof(BiTNode));memset(&b5, 0, sizeof(BiTNode));memset(&b6, 0, sizeof(BiTNode));memset(&b7, 0, sizeof(BiTNode));b1.nIndex = 0; b1.data = 'A';b2.nIndex = 1; b2.data = 'B';b3.nIndex = 2; b3.data = 'C';b4.nIndex = 3; b4.data = 'D';b5.nIndex = 4; b5.data = 'E';b6.nIndex = 5; b6.data = 'F';b7.nIndex = 6; b7.data = 'G';//构建树关系b1.lchild = &b2;b1.rchild = &b3;b2.lchild = &b4;b2.rchild = &b5;//根
b6.lchild = &b1;
b6.rchild = &b7;cout << "LCA1:\n";DFS(&b6, 0, -1);int nIndex = LCA1(b1.nIndex, b2.nIndex);if (nIndex >= 0){printf("LCA(%c,%c)= index(%d)\n", b1.data, b2.data, nIndex);}nIndex = LCA1(b5.nIndex, b7.nIndex);if (nIndex >= 0){printf("LCA(%c,%c)= index(%d)\n", b5.data, b7.data, nIndex);}//LCA2cout << "LCA2:\n";BiTNode *pLCA = LCA2(&b6, &b1, &b2);if (pLCA){printf("LCA(%c,%c)= %c\n",b1.data,b2.data, pLCA->data);}pLCA = LCA2(&b6, &b5, &b7);if (pLCA){printf("LCA(%c,%c)= %c\n", b5.data, b7.data, pLCA->data);}system("pause");
}

http://www.ppmy.cn/news/287704.html

相关文章

数据结构-Redis(三)

前面介绍了redis的String和哈希&#xff0c;接下来看看其他的数据结构 List LPUSH&#xff1a;左边放入 RPUSH&#xff1a;右边放入 LPOP&#xff1a;取出左边第一个数&#xff0c;并且移除 RPOP&#xff1a;取出右边第一个数&#xff0c;并且移除 由上操作可以看出&#…

「HTML和CSS入门指南」aside 标签详解

什么是 aside 标签? 在 HTML 中,aside 标签用于表示与页面或文章内容相关,但又不属于主要内容的侧边栏、导航区域、广告、标注等内容。通常用于包含附加信息、引用和其他次要元素。 aside 标签的基本语法 以下是 aside 标签的基本语法: <aside><!-- 在这里放置您…

「HTML和CSS入门指南」figure 标签详解

什么是 figure 标签? 在 HTML 中,figure 标签用于表示媒体内容(例如图像、音频或视频)及其相关说明。通常用于包含一组相关的元素,以便可以将它们作为单个单元进行引用。 figure 标签的基本语法 以下是 figure 标签的基本语法: <figure><!-- 在这里放置您的媒…

silicompressor视频压缩

近期为了上次视频压缩慢&#xff0c;而且模糊的问题进行优化&#xff0c; 之前使用的是FFmpeg进行视频压缩&#xff0c;缺点&#xff0c;太慢&#xff0c;网上看了好多实现方法&#xff0c;最终还是对silicompressor下手了&#xff0c;&#xff08;哈哈&#xff09; 下面来介…

谈谈视频压缩管理器1(VCM)-Video Compress Manager

如要转贴请注明转至blog.csdn.net/suntaoznz。谢谢&#xff01; 视频压缩管理器&#xff08;VCM&#xff09; 视频压缩管理器提供了一个访问接口&#xff0c;通过该接口可以使用系统已经安装了的压缩器去压缩处理实时视频数据。应用程序可以使用安装的压缩器去执行下面的任务…

MPEG-4视频压缩基础

MPEG&#xff08;活动图象专家组&#xff09;成立于1988年&#xff0c;是国际标准化组织ISO&#xff08;The International Organization for Standardization&#xff09;和IEC&#xff08;International Electrotechnical Commission&#xff09;联合工作委员会(JTC1)在信息技…

【MySQL】常见数据类型

文章目录 整数类型浮点数类型和定点数类型字符串类型文本类型日期与时间类型YEAR类型TIME类型DATETIME类型TIMESTAMP类型 二进制类型 整数类型 根据数值取值范围的不同MySQL中的整数类型可分为5种&#xff0c;分别是TINYINT、SMALUNT、MEDIUMINT、INT和 BIGINT。 数据类型字节数…

[转载]探索高清电影里的无/有损压缩真面目

探索高清电影里的无/有损压缩真面目 本文转载于“ HDChina论坛s Archiver s ^_^” 探索高清电影里的无/有损压缩真面目大家在下载高清时&#xff0c;通常都只留意到画面品质是否是1080P&#xff0c;但你有没有留意到&#xff0c;为何同样规格同样影片时长的1080P影片有的容量达…