JZ-C-50

剑指offer第五十题:树中两个结点的最低公共祖先:这里的树是普通树,且没有指向父结点的指针。

  1 //============================================================================
  2 // Name        : JZ-C-50.cpp
  3 // Author      : Laughing_Lz
  4 // Version     :
  5 // Copyright   : All Right Reserved
  6 // Description : 树中两个结点的最低公共祖先:这里的树是普通树,且没有指向父结点的指针。
  7 //============================================================================
  8
  9 #include <iostream>
 10 #include <stdio.h>
 11 #include "Tree.h"
 12 #include <list>
 13 using namespace std;
 14
 15 using namespace std;
 16 /**
 17  * 获得从树的根结点到某结点的路径
 18  */
 19 bool GetNodePath(TreeNode* pRoot, TreeNode* pNode, list<TreeNode*>& path) {
 20     if (pRoot == pNode)
 21         return true;
 22
 23     path.push_back(pRoot);
 24
 25     bool found = false;
 26
 27     vector<TreeNode*>::iterator i = pRoot->m_vChildren.begin(); //这里的树为普通树,甚至不是二叉树。所以这里按照前序遍历子树即可。
 28     while (!found && i < pRoot->m_vChildren.end()) {
 29         found = GetNodePath(*i, pNode, path);
 30         ++i;
 31     }
 32
 33     if (!found)
 34         path.pop_back();
 35
 36     return found;
 37 }
 38 /**
 39  * 获得两条路径的最后一个公共结点。
 40  */
 41 TreeNode* GetLastCommonNode(const list<TreeNode*>& path1,
 42         const list<TreeNode*>& path2) {
 43     list<TreeNode*>::const_iterator iterator1 = path1.begin();
 44     list<TreeNode*>::const_iterator iterator2 = path2.begin();
 45
 46     TreeNode* pLast = NULL;
 47
 48     while (iterator1 != path1.end() && iterator2 != path2.end()) {
 49         if (*iterator1 == *iterator2)
 50             pLast = *iterator1; //遍历完两条路径,得到最后一个公共结点。
 51
 52         iterator1++;
 53         iterator2++;
 54     }
 55
 56     return pLast;
 57 }
 58
 59 TreeNode* GetLastCommonParent(TreeNode* pRoot, TreeNode* pNode1,
 60         TreeNode* pNode2) {
 61     if (pRoot == NULL || pNode1 == NULL || pNode2 == NULL)
 62         return NULL;
 63
 64     list<TreeNode*> path1;
 65     GetNodePath(pRoot, pNode1, path1);
 66
 67     list<TreeNode*> path2;
 68     GetNodePath(pRoot, pNode2, path2);
 69
 70     return GetLastCommonNode(path1, path2);
 71 }
 72
 73 // ====================测试代码====================
 74
 75 void Test(char* testName, TreeNode* pRoot, TreeNode* pNode1, TreeNode* pNode2,
 76         TreeNode* pExpected) {
 77     if (testName != NULL)
 78         printf("%s begins: \n", testName);
 79
 80     TreeNode* pResult = GetLastCommonParent(pRoot, pNode1, pNode2);
 81
 82     if ((pExpected == NULL && pResult == NULL)
 83             || (pExpected != NULL && pResult != NULL
 84                     && pResult->m_nValue == pExpected->m_nValue))
 85         printf("Passed.\n");
 86     else
 87         printf("Failed.\n");
 88 }
 89
 90 // 形状普通的树
 91 //              1
 92 //            /    93 //           2     3
 94 //       /        95 //      4         5
 96 //     / \      / |   97 //    6   7    8  9  10
 98 void Test1() {
 99     TreeNode* pNode1 = CreateTreeNode(1);
100     TreeNode* pNode2 = CreateTreeNode(2);
101     TreeNode* pNode3 = CreateTreeNode(3);
102     TreeNode* pNode4 = CreateTreeNode(4);
103     TreeNode* pNode5 = CreateTreeNode(5);
104     TreeNode* pNode6 = CreateTreeNode(6);
105     TreeNode* pNode7 = CreateTreeNode(7);
106     TreeNode* pNode8 = CreateTreeNode(8);
107     TreeNode* pNode9 = CreateTreeNode(9);
108     TreeNode* pNode10 = CreateTreeNode(10);
109
110     ConnectTreeNodes(pNode1, pNode2);
111     ConnectTreeNodes(pNode1, pNode3);
112
113     ConnectTreeNodes(pNode2, pNode4);
114     ConnectTreeNodes(pNode2, pNode5);
115
116     ConnectTreeNodes(pNode4, pNode6);
117     ConnectTreeNodes(pNode4, pNode7);
118
119     ConnectTreeNodes(pNode5, pNode8);
120     ConnectTreeNodes(pNode5, pNode9);
121     ConnectTreeNodes(pNode5, pNode10);
122
123     Test("Test1", pNode1, pNode6, pNode8, pNode2);
124 }
125
126 // 树退化成一个链表
127 //               1
128 //              /
129 //             2
130 //            /
131 //           3
132 //          /
133 //         4
134 //        /
135 //       5
136 void Test2() {
137     TreeNode* pNode1 = CreateTreeNode(1);
138     TreeNode* pNode2 = CreateTreeNode(2);
139     TreeNode* pNode3 = CreateTreeNode(3);
140     TreeNode* pNode4 = CreateTreeNode(4);
141     TreeNode* pNode5 = CreateTreeNode(5);
142
143     ConnectTreeNodes(pNode1, pNode2);
144     ConnectTreeNodes(pNode2, pNode3);
145     ConnectTreeNodes(pNode3, pNode4);
146     ConnectTreeNodes(pNode4, pNode5);
147
148     Test("Test2", pNode1, pNode5, pNode4, pNode3);
149 }
150
151 // 树退化成一个链表,一个结点不在树中
152 //               1
153 //              /
154 //             2
155 //            /
156 //           3
157 //          /
158 //         4
159 //        /
160 //       5
161 void Test3() {
162     TreeNode* pNode1 = CreateTreeNode(1);
163     TreeNode* pNode2 = CreateTreeNode(2);
164     TreeNode* pNode3 = CreateTreeNode(3);
165     TreeNode* pNode4 = CreateTreeNode(4);
166     TreeNode* pNode5 = CreateTreeNode(5);
167
168     ConnectTreeNodes(pNode1, pNode2);
169     ConnectTreeNodes(pNode2, pNode3);
170     ConnectTreeNodes(pNode3, pNode4);
171     ConnectTreeNodes(pNode4, pNode5);
172
173     TreeNode* pNode6 = CreateTreeNode(6);
174
175     Test("Test3", pNode1, pNode5, pNode6, NULL);
176 }
177
178 // 输入NULL
179 void Test4() {
180     Test("Test4", NULL, NULL, NULL, NULL);
181 }
182
183 int main(int argc, char** argv) {
184     Test1();
185     Test2();
186     Test3();
187     Test4();
188
189     return 0;
190 }
时间: 2024-10-21 20:22:48

JZ-C-50的相关文章

Kotlin 的现状和未来

Andrey Breslav,Kotlin 项目负责人,今天他以一个工具开发者和工具生态系统的角度来给我们介绍 Kotlin 的概况.然后他会讲讲未来和他们下个版本的一些信息. 我的名字叫 Andrey,我在 JetBrains 带领着 Kotlin 团队.今天我来和大家聊聊我们现在的状态和未来的计划. 这篇演讲不是 Kotlin 的入门介绍.如果你想学习 Kotlin,到处都能找到学习的资源.这里有一个 语言参考,教程,演讲视频 .试试我们的 mini-IDE ,Kotlin Koans 是一

汇编程序:进制转换程序

设计内容 1.从键盘输入一个不少于8位的十进制数(如12345678),把其分别转换成二进制.八进制.十六进制数显示在屏幕上. 2.从键盘输入一个不少于5位的十六进制数(如1FED5H),把其分别转换成二进制.八进制.十进制数显示在屏幕上. 思路 1.本程序应用分支程序功能实现菜单选择操作,在主程序中通过带参数的调用子函数,来完成部分功能的实现. 2.子程序decin:实现十进制的输入功能,设一个计数器,保存输入字符的个数,因为输入的是十进制数,对其输入进行了严格的审核,防止出现乱码的情况,采用

酷炫ILOVEU

1 assume cs:code 2 3 code segment 4 main: 5 mov cx,880 ;显示背景22*80 6 mov dh,0 ;dh中放行号 7 mov dl,0 ;dl中放列号 8 bibi: 9 push cx 10 mov ah,2 ;显示光标 11 mov bh,0 ;第0页 12 int 10h 13 14 ;在光标处显示个数自定的字符 15 mov ah,9 ;9为在"在光标处显示字符的功能"的功能号 16 mov al,'0' ;字符 17 m

[汇编] 统计字符

1 ;编写一个有主程序和子程序结构的程序模块. 2 ;子程序的参数是一个N字节数组的首地址TABLE,数N及字符CHAR. 3 ;要求在N字节数组中查找字符CHAR,并记录该字符出现的次数. 4 ;主程序则要求从键盘接收一串字符以建立字节数组TABLE, 5 ;并逐个显示从键盘输入的每个字符CHAR以及它在TABLE数组中出现的次数. 6 ;(为简化起见,假设出现次数≤15,可以用16进制形式把它显示出来.) 7 8 data segment 9 table db 255 dup(0) 10 n

C++学习笔记50:队列类模板

队列是只能向一端添加元素,从另一端删除元素的线性群体 循环队列 在想象中将数组弯曲成环形,元素出队时,后继元素不移动,每当队尾达到数组最后一个元素时,便再回到数组开头. 队列类模板 //Queue.h #ifndef QUEUE_H #define QUEUE_H #include <cassert> //类模板的定义 template <class T, int SIZE = 50> class Queue { private: int front, rear, count; T

2016年 CSS 库、框架和工具新生榜 TOP 50

看看 CSS 在过去几年的巨大变化和快速发展,你就不会对它今年的开源工具大产量感到惊讶了.这些 CSS 库.框架和工具的建立不仅给我们提供了学习的视角,更给我们的工作与生活带来了便利. 本文精选了 50 款 2016 年发布的 CSS 库.框架和工具供大家享用,希望它们对您有所帮助. 分类快速预览:CSS 库,CSS Spinners,CSS 图像特效,CSS 实用程序,设计指南工具,响应式邮件与通讯列表框架,Flexbox 布局工具和框架,CSS 布局框架和 material design 框

设计一个Shell程序,在/userdata目录下建立50个目录,即user1~user50,并设置每个目录的权限为 rwxr-xr—

#!/bin/bash cd /userdata i=1 while [ $i -le 50 ] do mkdir -p /userdata/user$i chmod o-x user$i i=$((i+1)) done

E3-1260L (8M Cache, 2.40 GHz) E3-1265L v2 (8M Cache, 2.50 GHz)

http://ark.intel.com/compare/52275,65728       Product Name Intel® Xeon® Processor E3-1260L (8M Cache, 2.40 GHz) Intel® Xeon® Processor E3-1265L v2 (8M Cache, 2.50 GHz) Code Name Sandy Bridge Ivy Bridge Essentials Status End of Life Launched Launch D

使用Unity3D的50个技巧:Unity3D最佳实践

刚开始学习Unity3D时间不长,在看各种资料.除了官方的手册以外,其他人的经验也是非常有益的.偶尔看到老外这篇文章,觉得还不错,于是翻译过来和大家共享.原文地址:http://devmag.org.za/2012/07/12/50-tips-for-working-with-unity-best-practices/,下面是译文. 欢迎转载,请注明出处:燕良@游戏开发.另外,欢迎各路高手加入我的QQ群:264656505,切磋交流技术. 关于这些技巧 这些技巧不可能适用于每个项目. 这些是基于

50个常用的sql语句

50个常用的sql语句 Student(S#,Sname,Sage,Ssex) 学生表 Course(C#,Cname,T#) 课程表 SC(S#,C#,score) 成绩表 Teacher(T#,Tname) 教师表 问题: 1.查询"001"课程比"002"课程成绩高的所有学生的学号: select a.S# from (select s#,score from SC where C#='001') a,(select s#,score from SC wher