案例二 树中两个结点的最低公共祖先

2024-06-21 23:48

本文主要是介绍案例二 树中两个结点的最低公共祖先,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

      问题: 树中两个结点的最低公共祖先.

    (1)是一颗二叉树,并且是二叉搜素树(根据二叉搜素树的性质求解

    (2)普通树中结点有指向父结点的指针(演变为两个链表求解第一个公共结点)


    (3)一棵普通的树,树中的结点没有指向父结点的指针(最复杂的情况)


通用的解法如下:

//记录结点的路径
bool GetNodePath(TreeNode* pRoot, TreeNode* pNode, list<TreeNode*>& path)
{if(pRoot == pNode)return true;path.push_back(pRoot);bool found = false;vector<TreeNode*>::iterator i = pRoot->m_vChildren.begin();while(!found && i < pRoot->m_vChildren.end()){found = GetNodePath(*i, pNode, path);++i;}if(!found)path.pop_back();return found;
}TreeNode* GetLastCommonNode( const list<TreeNode*>& path1,  const list<TreeNode*>& path2)
{list<TreeNode*>::const_iterator iterator1 = path1.begin();list<TreeNode*>::const_iterator iterator2 = path2.begin();TreeNode* pLast = NULL;while(iterator1 != path1.end() && iterator2 != path2.end()){if(*iterator1 == *iterator2)pLast = *iterator1;iterator1++;iterator2++;}return pLast;
}
//获取最低的公共父结点
TreeNode* GetLastCommonParent(TreeNode* pRoot, TreeNode* pNode1, TreeNode* pNode2)
{if(pRoot == NULL || pNode1 == NULL || pNode2 == NULL)return NULL;list<TreeNode*> path1;GetNodePath(pRoot, pNode1, path1);list<TreeNode*> path2;GetNodePath(pRoot, pNode2, path2);return GetLastCommonNode(path1, path2);
}// ====================测试代码====================void Test(char* testName, TreeNode* pRoot, TreeNode* pNode1, TreeNode* pNode2, TreeNode* pExpected)
{if(testName != NULL)printf("%s begins: \n", testName);TreeNode* pResult = GetLastCommonParent(pRoot, pNode1, pNode2);if((pExpected == NULL && pResult == NULL) || (pExpected != NULL && pResult != NULL && pResult->m_nValue == pExpected->m_nValue))printf("Passed.\n");elseprintf("Failed.\n");
}// 形状普通的树
//              1
//            /   \
//           2     3
//       /       \
//      4         5
//     / \      / |  \
//    6   7    8  9  10
void Test1()
{TreeNode* pNode1 = CreateTreeNode(1);TreeNode* pNode2 = CreateTreeNode(2);TreeNode* pNode3 = CreateTreeNode(3);TreeNode* pNode4 = CreateTreeNode(4);TreeNode* pNode5 = CreateTreeNode(5);TreeNode* pNode6 = CreateTreeNode(6);TreeNode* pNode7 = CreateTreeNode(7);TreeNode* pNode8 = CreateTreeNode(8);TreeNode* pNode9 = CreateTreeNode(9);TreeNode* pNode10 = CreateTreeNode(10);ConnectTreeNodes(pNode1, pNode2);ConnectTreeNodes(pNode1, pNode3);ConnectTreeNodes(pNode2, pNode4);ConnectTreeNodes(pNode2, pNode5);ConnectTreeNodes(pNode4, pNode6);ConnectTreeNodes(pNode4, pNode7);ConnectTreeNodes(pNode5, pNode8);ConnectTreeNodes(pNode5, pNode9);ConnectTreeNodes(pNode5, pNode10);Test("Test1", pNode1, pNode6, pNode8, pNode2);
}// 树退化成一个链表
//               1
//              /
//             2
//            /
//           3
//          /
//         4
//        /
//       5
void Test2()
{TreeNode* pNode1 = CreateTreeNode(1);TreeNode* pNode2 = CreateTreeNode(2);TreeNode* pNode3 = CreateTreeNode(3);TreeNode* pNode4 = CreateTreeNode(4);TreeNode* pNode5 = CreateTreeNode(5);ConnectTreeNodes(pNode1, pNode2);ConnectTreeNodes(pNode2, pNode3);ConnectTreeNodes(pNode3, pNode4);ConnectTreeNodes(pNode4, pNode5);Test("Test2", pNode1, pNode5, pNode4, pNode3);
}// 树退化成一个链表,一个结点不在树中
//               1
//              /
//             2
//            /
//           3
//          /
//         4
//        /
//       5
void Test3()
{TreeNode* pNode1 = CreateTreeNode(1);TreeNode* pNode2 = CreateTreeNode(2);TreeNode* pNode3 = CreateTreeNode(3);TreeNode* pNode4 = CreateTreeNode(4);TreeNode* pNode5 = CreateTreeNode(5);ConnectTreeNodes(pNode1, pNode2);ConnectTreeNodes(pNode2, pNode3);ConnectTreeNodes(pNode3, pNode4);ConnectTreeNodes(pNode4, pNode5);TreeNode* pNode6 = CreateTreeNode(6);Test("Test3", pNode1, pNode5, pNode6, NULL);
}// 输入NULL
void Test4()
{Test("Test4", NULL, NULL, NULL, NULL);
}int _tmain(int argc, _TCHAR* argv[])
{Test1();Test2();Test3();Test4();return 0;
}




这篇关于案例二 树中两个结点的最低公共祖先的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1082691

相关文章

Python中re模块结合正则表达式的实际应用案例

《Python中re模块结合正则表达式的实际应用案例》Python中的re模块是用于处理正则表达式的强大工具,正则表达式是一种用来匹配字符串的模式,它可以在文本中搜索和匹配特定的字符串模式,这篇文章主... 目录前言re模块常用函数一、查看文本中是否包含 A 或 B 字符串二、替换多个关键词为统一格式三、提

Python get()函数用法案例详解

《Pythonget()函数用法案例详解》在Python中,get()是字典(dict)类型的内置方法,用于安全地获取字典中指定键对应的值,它的核心作用是避免因访问不存在的键而引发KeyError错... 目录简介基本语法一、用法二、案例:安全访问未知键三、案例:配置参数默认值简介python是一种高级编

MySQL中的索引结构和分类实战案例详解

《MySQL中的索引结构和分类实战案例详解》本文详解MySQL索引结构与分类,涵盖B树、B+树、哈希及全文索引,分析其原理与优劣势,并结合实战案例探讨创建、管理及优化技巧,助力提升查询性能,感兴趣的朋... 目录一、索引概述1.1 索引的定义与作用1.2 索引的基本原理二、索引结构详解2.1 B树索引2.2

从入门到精通MySQL 数据库索引(实战案例)

《从入门到精通MySQL数据库索引(实战案例)》索引是数据库的目录,提升查询速度,主要类型包括BTree、Hash、全文、空间索引,需根据场景选择,建议用于高频查询、关联字段、排序等,避免重复率高或... 目录一、索引是什么?能干嘛?核心作用:二、索引的 4 种主要类型(附通俗例子)1. BTree 索引(

HTML中meta标签的常见使用案例(示例详解)

《HTML中meta标签的常见使用案例(示例详解)》HTMLmeta标签用于提供文档元数据,涵盖字符编码、SEO优化、社交媒体集成、移动设备适配、浏览器控制及安全隐私设置,优化页面显示与搜索引擎索引... 目录html中meta标签的常见使用案例一、基础功能二、搜索引擎优化(seo)三、社交媒体集成四、移动

六个案例搞懂mysql间隙锁

《六个案例搞懂mysql间隙锁》MySQL中的间隙是指索引中两个索引键之间的空间,间隙锁用于防止范围查询期间的幻读,本文主要介绍了六个案例搞懂mysql间隙锁,具有一定的参考价值,感兴趣的可以了解一下... 目录概念解释间隙锁详解间隙锁触发条件间隙锁加锁规则案例演示案例一:唯一索引等值锁定存在的数据案例二:

MySQL 表的内外连接案例详解

《MySQL表的内外连接案例详解》本文给大家介绍MySQL表的内外连接,结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录表的内外连接(重点)内连接外连接表的内外连接(重点)内连接内连接实际上就是利用where子句对两种表形成的笛卡儿积进行筛选,我

Java Stream.reduce()方法操作实际案例讲解

《JavaStream.reduce()方法操作实际案例讲解》reduce是JavaStreamAPI中的一个核心操作,用于将流中的元素组合起来产生单个结果,:本文主要介绍JavaStream.... 目录一、reduce的基本概念1. 什么是reduce操作2. reduce方法的三种形式二、reduce

Spring Boot 整合 Redis 实现数据缓存案例详解

《SpringBoot整合Redis实现数据缓存案例详解》Springboot缓存,默认使用的是ConcurrentMap的方式来实现的,然而我们在项目中并不会这么使用,本文介绍SpringB... 目录1.添加 Maven 依赖2.配置Redis属性3.创建 redisCacheManager4.使用Sp

springboot项目redis缓存异常实战案例详解(提供解决方案)

《springboot项目redis缓存异常实战案例详解(提供解决方案)》redis基本上是高并发场景上会用到的一个高性能的key-value数据库,属于nosql类型,一般用作于缓存,一般是结合数据... 目录缓存异常实践案例缓存穿透问题缓存击穿问题(其中也解决了穿透问题)完整代码缓存异常实践案例Red