(6)从数据结构中树的定义可知,除根结点外,树中的每个结点都有唯一的一个双亲结点。根据这一特性,可用一组连续的存储空间(一维数组)存储树中的各结点。树中的结点除保存结点本身的信息之外,还要保存其双亲结点在数组中的位置(即在数组中的下标。双亲的信息为-1则表示该结点为根结点),树的这种表示法称为双亲表示法。
树的每个结点的数据类型定义如下: struct PTNode { char data; //结点数据域 int
parent; //结点双亲在数组中的位置 }; 树的数据类型定义如下:
#define MAX_TREE_SIZE 100 struct PTree { struct PTNode nodes[MAX_TREE_SIZE]; //存储树中所有结点 int n; //树中共有n个结点,n不超过100 };
则下图1所示的树,按照双亲表示法存储结构,存储为图2所示形式(n为10)。

已知一棵树已存储为以上形式,请编写函数GetNearestCommonGrand,查找给定的两个(不相同的)结点最近的共同祖先。GetNearestCommonGrand的函数原型为:
char GetNearestCommonGrand(struct PTree T, char nodeData1, char
nodeData2) 函数形参: T:保存了树中结点数目及图2所示的结点数组
nodeData1,nodeData2:给定的两个结点的数据(输入时保证这两个结点存在)。 函数返回值: 两个结点最近的共同祖先。
比如,nodeData1为’G’,nodeData2为’H’,则函数返回’A’。
说明:输入保证nodeData1和nodeData2在树中能找到。

部分代码在prog3.c中,请仅在GetNearestCommonGrand函数中填入内容,完成程序。
要求:尽量优化算法的时间复杂度与空间复杂度,并在GetNearestCommonGrand函数前的注释部分简要介绍自己的算法,同时指出该算法具有什么样的时间复杂度与空间复杂度。
请勿改动主函数main和其它已有函数中的任何内容,可以在函数GetNearestCommonGrand的花括号中填入你编写的若干语句,允许增加自定义函数。

prog3.c中,struct PTree
CreateTree()函数用于从键盘输入树的双亲表示法的信息,创建一棵树。输入的第一个数n表示树中结点数,此后有n行输入,每行表示一个结点的信息,其中第一个信息为结点的数据,第二个信息为结点的双亲结点在数组中的位置。
在main函数中还需要输入两个结点的字符数据,查询这两个结点的最近共同祖先。

如输入(第一行为n,表示共有10个结点,后面10行,为10个结点的信息,最后一行为g和h,表示查询结点g和结点h的最近共同祖先): 10 a
-1 b 0 c 0 d 0 e 1 f 1 g 1 h 2 i 3 j 3 g h 则将创建图b所对应的树。 输出结果为’a’

如输入: 8 a -1 b 0 e 1 h 6 c 0 d 0 f 5 g 5 g h 输出结果为’d’

我的想法是:先找出两结点的所有祖先结点,存储在两个不同的数组中。然后比对两个数组,找出第一个公共祖先结点即可
初始代码如下:

#include <stdio.h>
#define MAX_TREE_SIZE 100
void NONO();
struct PTNode /*树的一个结点*/
{char data;int parent; /* 双亲位置域 */
};
struct PTree
{    struct PTNode nodes[MAX_TREE_SIZE];int n; /* 结点数 */
};
/*
请在此介绍自己的算法,并解释算法的时间复杂度与空间复杂度往上找结点的祖先,将祖先分别存在两个数组中。比对这两个数组,找出最先重合的祖先即可。
*/
char GetNearestCommonGrand(struct PTree T, char nodeData1, char nodeData2)
{char ances1[MAX_TREE_SIZE], ances2[MAX_TREE_SIZE];// 存放两结点的祖先结点struct PTNode p, q;// 工作指针int i = 0, j = 0, m = 0, n = 0;for (i = 0; i < T.n; i++) {// 根据两结点数据确定两结点if (T.nodes[i].data == nodeData1) {p = T.nodes[i];}if (T.nodes[i].data == nodeData2) {q = T.nodes[i];}}i = 0, j = 0;p = T.nodes[p.parent];while (1) {// 得到第一个结点的所有祖先ances1[i++] = p.data;p = T.nodes[p.parent];if (p.parent == -1) {break;}}q = T.nodes[q.parent];while (1) {// 得到第二个结点的所有祖先ances2[j++] = q.data;q = T.nodes[q.parent];if (q.parent == -1) {break;}}for (m = 0; m < i; m++) {// 比对两结点的祖先,找出最近的共同祖先for (n = 0; n < j; n++) {if (ances1[m] == ances2[n]) {return ances1[m];}}}return (char) 0;}
struct PTree CreateTree()
{int i,n;int parentId;char ch;struct PTree newTree;scanf("%d", &n);newTree.n=n;for (i = 0; i < n; i++){scanf(" %c%d", &ch, &parentId);newTree.nodes[i].data=ch;newTree.nodes[i].parent=parentId;}return newTree;
}
int main()
{struct PTree aTree;char node1, node2, nodeGrand;aTree = CreateTree();scanf(" %c %c", &node1, &node2);nodeGrand= GetNearestCommonGrand (aTree, node1, node2);printf("%c\n", nodeGrand);//NONO();return 0;
}
void NONO()
{//本函数用于辅助教师判卷,不需要阅读其中代码,也请不要改动其中代码。FILE *fp, *wf ;int i,j,n;char ch;int parentId;char node1, node2, nodeGrand;struct PTree newTree;fp = fopen("p3.in","r");wf = fopen("p3.out","w");for(i = 0 ; i < 6 ; i++){fscanf(fp, "%d", &n);newTree.n=n;for (j = 0; j < n; j++){fscanf(fp," %c%d", &ch, &parentId);newTree.nodes[j].data=ch;newTree.nodes[j].parent=parentId;}fscanf(fp," %c %c", &node1, &node2);nodeGrand= GetNearestCommonGrand (newTree, node1, node2);fprintf(wf, "%c\n", nodeGrand);}fclose(fp);fclose(wf);
}

结果如下:

看到这里我就有点奇怪了,怎么会输出空格呢?调试后发现问题出在这里:

这里1和2的顺序反了,这就导致根结点没有被保存下来,所以会输出空格。改过来就好啦

下次写while循环一定要注意语句的书写顺序呀

东华复试上机备考踩坑记-17年第三题相关推荐

  1. 环信SDK 踩坑记webIM篇(三)

    问题:接收消息时报错 TypeError: Cannot read property 'isemoji' of undefined at connection.handleMessage 自己打开了w ...

  2. IdentityServer 部署踩坑记

    IdentityServer 部署踩坑记 Intro 周末终于部署了 IdentityServer 以及 IdentityServerAdmin 项目,踩了几个坑,在此记录分享一下. 部署架构 项目是 ...

  3. python从入门到实践django看不懂_Python编程:从入门到实践踩坑记 Django

    <>踩坑记 Django Django Python 19.1.1.5 模板new_topic 做完书上的步骤后,对主题添加页面经行测试,但是浏览器显示 服务器异常. 个人采用的开发环境是 ...

  4. 东八区转为0时区_踩坑记 | Flink 天级别窗口中存在的时区问题

    ❝ 本系列每篇文章都是从一些实际的 case 出发,分析一些生产环境中经常会遇到的问题,抛砖引玉,以帮助小伙伴们解决一些实际问题.本文介绍 Flink 时间以及时区问题,分析了在天级别的窗口时会遇到的 ...

  5. Spring @Transactional踩坑记

    @Transactional踩坑记 总述 ​ Spring在1.2引入@Transactional注解, 该注解的引入使得我们可以简单地通过在方法或者类上添加@Transactional注解,实现事务 ...

  6. 服务器重新部署踩坑记

    服务器重新部署踩坑记 Intro 之前的服务器是 Ubuntu 18.04 ,上周周末想升级一下服务器系统,从 18.04 升级到 20.04,结果升级升挂了... 后来 SSH 始终连不上,索性删除 ...

  7. windows container 踩坑记

    windows container 踩坑记 Intro 我们有一些服务是 dotnet framework 的,不能直接跑在 docker linux container 下面,最近一直在折腾把它部署 ...

  8. Spark踩坑记——数据库(Hbase+Mysql)转

    转自:http://www.cnblogs.com/xlturing/p/spark.html 前言 在使用Spark Streaming的过程中对于计算产生结果的进行持久化时,我们往往需要操作数据库 ...

  9. android小程序_小程序踩坑记

    小程序踩坑记 希望这个文章能尽量记录下小程序的那些坑,避免开发者们浪费自己的生命来定位到底是自己代码导致的还是啥神秘的字节跳变原因. 前记 小程序大多数坑是同一套代码在不同平台上表现不一致导致的,微信 ...

最新文章

  1. php protected 属性,PHP实现在对象之外访问其私有属性private及保护属性protected的方法...
  2. 《2019中国硬科技发展白皮书》发布,中美硬科技创新指数PK
  3. Java异常之异常机制
  4. iOS设计模式——MVC(Model-View-Controller)
  5. c++ 判断数学表达式有效性_高考数学大题如何quot;保分quot;?学霸教你六大绝招!...
  6. thread php,php中关于线程thread的使用
  7. php连接mongoDB的几个问题
  8. html flash 循环播放,在网页中插入flv格式的flash视频怎么让其循环播放_html/css_WEB-ITnose...
  9. Python datetime time
  10. java安卓开发异步任务_java – 如何从android中的任何异步操作中获...
  11. 第四季-专题5-内核模块开发
  12. Atitit 项目语言的选择 java c#.net  php??
  13. LeetCode算法题-Binary Number with Alternating Bits(Java实现)
  14. MATLAB高斯平顶化,一种高斯光束变换为平顶光束整形透镜的粒子群设计方法与流程...
  15. 析取范式、合取范式、主析取和主合取
  16. websocket服务端和html客户端进行二进制数据交互
  17. initial-scale
  18. Expected tensor for argument #1 ‘indices‘ to have one of the following scalar types: Long, Int; but
  19. CDN行业鼻祖Akamai的新航道:智能边缘+云安全
  20. Maven聚合项目搭建集成knife4j

热门文章

  1. Spring中用了哪些设计模式
  2. ROS-rosserial概述(1)
  3. 数据可视化大屏选型调研报告
  4. w的学习笔记01.(2019年1月7日)
  5. [喵咪大数据]Presto查询引擎
  6. 逻辑分页与物理分页的区别
  7. C++类与对象(下)
  8. Windows开机缓慢解决方法
  9. 2021_AAAI_Knowledge-aware Coupled Graph Neural Network for Social Recommendation
  10. “二维码”提交作业 学生们怒赞