[树] 求树(孩子链表)的深度 与其他基本操作(严蔚敏《数据结构》6.63)

本文主要是介绍[树] 求树(孩子链表)的深度 与其他基本操作(严蔚敏《数据结构》6.63),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目来源:严蔚敏《数据结构》C语言版本习题册 6.63

【题目】对以孩子链表表示的树编写计算树的深度的算法

【答案】

/*-------------------------|6.63 求树的深度         |-------------------------*/
int SubTreeDepth(CTree T, int index) { //序号为index的子树深度int max=-1; //孩子的最大深度int sd; //孩子的深度CNode *p;if (!T.nodes[index].firstchild) return 1; //没有孩子,深度为1for (p=T.nodes[index].firstchild; p; p=p->next) { //遍历该结点的所有孩子sd = SubTreeDepth(T, p->index); //求孩子的深度if (max<sd) max=sd;}return max+1; //孩子的最大深度+1
}
int TreeDepth(CTree T) { return SubTreeDepth(T, T.r);
}

【其他基本操作】

// 树的层序次序+每个结点的度 --> 创建CTree
Status CreateCTreeByLevelDegree(CTree *pT,char *levelstr, int *degree) {CNode *c,*sibling;int parent;int i,cnt;//创建结点for (i=0; i<strlen(levelstr); ++i) {//赋值pT->nodes[i].data = levelstr[i];pT->nodes[i].firstchild = NULL;}pT->n=strlen(levelstr); //个数pT->r=0; //根结点//为孩子找爸爸parent=0; //当前的爸爸i=1; //遍历孩子cnt=0; //已经为parent找到了cnt个孩子while (i<strlen(levelstr)) {if (degree[parent]==0 || cnt==degree[parent]) { //parent没有孩子 || parent的孩子已经全部找到cnt=0;parent++;continue;}cnt++; //为parent找到了一个孩子//创建孩子结点c = (CNode *)malloc(sizeof(CNode)); if (!c) exit(OVERFLOW);c->index = i; //孩子的编号c->next = NULL;if (cnt==1) { //第一个孩子pT->nodes[parent].firstchild = c;} else { //不是第一个孩子for(sibling=pT->nodes[parent].firstchild; sibling->next; sibling=sibling->next) ;sibling->next = c;}i++;}return TRUE;
}
// 先根遍历
void SubPreOrder(CTree T, int index) {CNode *child;visit(T.nodes[index].data);for (child=T.nodes[index].firstchild; child; child=child->next)SubPreOrder(T, child->index);
}
void PreOrder(CTree T) {SubPreOrder(T, T.r);
}

【完整代码】

#include<stdio.h>
#include<stdlib.h>
#include<string.h>#ifndef BASE
#define BASE
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;
typedef int bool;
#endif#define TElemType char
void visit(TElemType e) {printf("%c", e);
}
#define MAX_TREE_SIZE 100
#define maxSize 50typedef struct CNode{int index; //这个孩子的结点号(注意:在严书中变量名为child)struct CNode *next; //下一个孩子结点
}CNode, *ChildPtr; //孩子结点结构(在严书中名为CTNode)
typedef struct{TElemType data;CNode* firstchild;
}PNode; //双亲结点结构(在严书中,结构名为CTBox)
typedef struct{PNode nodes[MAX_TREE_SIZE];int n,r; //结点数 和 根结点的位置
}CTree; //树结构// 先根遍历
void SubPreOrder(CTree T, int index) {CNode *child;visit(T.nodes[index].data);for (child=T.nodes[index].firstchild; child; child=child->next)SubPreOrder(T, child->index);
}
void PreOrder(CTree T) {SubPreOrder(T, T.r);
}/*-------------------------|6.63 求树的深度         |-------------------------*/
int SubTreeDepth(CTree T, int index) { //序号为index的子树深度int max=-1; //孩子的最大深度int sd; //孩子的深度CNode *p;if (!T.nodes[index].firstchild) return 1; //没有孩子,深度为1for (p=T.nodes[index].firstchild; p; p=p->next) { //遍历该结点的所有孩子sd = SubTreeDepth(T, p->index); //求孩子的深度if (max<sd) max=sd;}return max+1; //孩子的最大深度+1
}
int TreeDepth(CTree T) { return SubTreeDepth(T, T.r);
}// 树的层序次序+每个结点的度 --> 创建CTree
Status CreateCTreeByLevelDegree(CTree *pT,char *levelstr, int *degree) {CNode *c,*sibling;int parent;int i,cnt;//创建结点for (i=0; i<strlen(levelstr); ++i) {//赋值pT->nodes[i].data = levelstr[i];pT->nodes[i].firstchild = NULL;}pT->n=strlen(levelstr); //个数pT->r=0; //根结点//为孩子找爸爸parent=0; //当前的爸爸i=1; //遍历孩子cnt=0; //已经为parent找到了cnt个孩子while (i<strlen(levelstr)) {if (degree[parent]==0 || cnt==degree[parent]) { //parent没有孩子 || parent的孩子已经全部找到cnt=0;parent++;continue;}cnt++; //为parent找到了一个孩子//创建孩子结点c = (CNode *)malloc(sizeof(CNode)); if (!c) exit(OVERFLOW);c->index = i; //孩子的编号c->next = NULL;if (cnt==1) { //第一个孩子pT->nodes[parent].firstchild = c;} else { //不是第一个孩子for(sibling=pT->nodes[parent].firstchild; sibling->next; sibling=sibling->next) ;sibling->next = c;}i++;}return TRUE;
}int main() {
/*6.63测试数据
RABCDEFGHI
3 2 0 1 0 0 3 0 0 0
*/CTree T;char levelstr[50];int num[50];int cnt;scanf("%s", levelstr);for (cnt=0; cnt<strlen(levelstr); cnt++) scanf("%d", &num[cnt]);CreateCTreeByLevelDegree(&T, levelstr, num);PreOrder(T);cnt = SubTreeDepth(T, T.r);printf("\nSubTreeDepth:%d\n", cnt);return 0;
}

这篇关于[树] 求树(孩子链表)的深度 与其他基本操作(严蔚敏《数据结构》6.63)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Linux链表操作方式

《Linux链表操作方式》:本文主要介绍Linux链表操作方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、链表基础概念与内核链表优势二、内核链表结构与宏解析三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势六、典型应用场景七、调试技巧与

Python中文件读取操作漏洞深度解析与防护指南

《Python中文件读取操作漏洞深度解析与防护指南》在Web应用开发中,文件操作是最基础也最危险的功能之一,这篇文章将全面剖析Python环境中常见的文件读取漏洞类型,成因及防护方案,感兴趣的小伙伴可... 目录引言一、静态资源处理中的路径穿越漏洞1.1 典型漏洞场景1.2 os.path.join()的陷

Spring Boot拦截器Interceptor与过滤器Filter深度解析(区别、实现与实战指南)

《SpringBoot拦截器Interceptor与过滤器Filter深度解析(区别、实现与实战指南)》:本文主要介绍SpringBoot拦截器Interceptor与过滤器Filter深度解析... 目录Spring Boot拦截器(Interceptor)与过滤器(Filter)深度解析:区别、实现与实

MyBatis分页插件PageHelper深度解析与实践指南

《MyBatis分页插件PageHelper深度解析与实践指南》在数据库操作中,分页查询是最常见的需求之一,传统的分页方式通常有两种内存分页和SQL分页,MyBatis作为优秀的ORM框架,本身并未提... 目录1. 为什么需要分页插件?2. PageHelper简介3. PageHelper集成与配置3.

Maven 插件配置分层架构深度解析

《Maven插件配置分层架构深度解析》:本文主要介绍Maven插件配置分层架构深度解析,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录Maven 插件配置分层架构深度解析引言:当构建逻辑遇上复杂配置第一章 Maven插件配置的三重境界1.1 插件配置的拓扑

Python中__init__方法使用的深度解析

《Python中__init__方法使用的深度解析》在Python的面向对象编程(OOP)体系中,__init__方法如同建造房屋时的奠基仪式——它定义了对象诞生时的初始状态,下面我们就来深入了解下_... 目录一、__init__的基因图谱二、初始化过程的魔法时刻继承链中的初始化顺序self参数的奥秘默认

C#数据结构之字符串(string)详解

《C#数据结构之字符串(string)详解》:本文主要介绍C#数据结构之字符串(string),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录转义字符序列字符串的创建字符串的声明null字符串与空字符串重复单字符字符串的构造字符串的属性和常用方法属性常用方法总结摘

SpringCloud动态配置注解@RefreshScope与@Component的深度解析

《SpringCloud动态配置注解@RefreshScope与@Component的深度解析》在现代微服务架构中,动态配置管理是一个关键需求,本文将为大家介绍SpringCloud中相关的注解@Re... 目录引言1. @RefreshScope 的作用与原理1.1 什么是 @RefreshScope1.

Python 中的异步与同步深度解析(实践记录)

《Python中的异步与同步深度解析(实践记录)》在Python编程世界里,异步和同步的概念是理解程序执行流程和性能优化的关键,这篇文章将带你深入了解它们的差异,以及阻塞和非阻塞的特性,同时通过实际... 目录python中的异步与同步:深度解析与实践异步与同步的定义异步同步阻塞与非阻塞的概念阻塞非阻塞同步

Redis中高并发读写性能的深度解析与优化

《Redis中高并发读写性能的深度解析与优化》Redis作为一款高性能的内存数据库,广泛应用于缓存、消息队列、实时统计等场景,本文将深入探讨Redis的读写并发能力,感兴趣的小伙伴可以了解下... 目录引言一、Redis 并发能力概述1.1 Redis 的读写性能1.2 影响 Redis 并发能力的因素二、