广义表之树的兄弟孩子表示法
title: 广义表之树的兄弟孩子表示法
date: 2020-11-17 15:55:55
tags:
- 兄弟孩子广义表
- 二叉树
categories: 数据结构
用兄弟孩子广义表来表示二叉树
对比
二叉树转化来的兄弟孩子广义表和普通的兄弟孩子广义表并不相同
二叉树转换成的兄弟孩子广义表没有明确的一块内存结构来直接表示它是叶子节点还是双亲结点,而是通过 指针
tp
来隐式地表示,tp
指向空,表示它没有孩子节点,否则,有孩子结点普通的兄弟孩子广义表则是通过
tag
= 0 或 1 来表示它是否还有孩子结点普通的广义表如果转换成树,那么转换成的是只有在叶子结点中存数据的树,根结点,和树中间的双亲节点可以理解成一级一级的括号。
如果还要说不同的话,那就是二叉树中一个双亲结点最多有2 个孩子结点, 而普通的广义表则不同
在求深度的时候,刚开始要设一个
max = 0
来表示下一层的深度的最大值, 树转换来的兄弟孩子广义表,下一层只要有结点,那么下一层的深度必为 1 ,直接return max + 1
即可,但是普通的广义表,下一层有结点的时候并不能代表下一层的深度就是 1, 因为如果下一层都是 tag为 0 的结点,那么下一层的深度就都是 0 ,不可return max + 1
, 需要return max
,return max + 1
和return max
的情况需要 分开讨论关于两种不同的兄弟孩子广义表求深度时候具体细节的不同,我会在下一期中具体分析
总结
总结一下不同的树 转换成表
- 二叉树 转换成兄弟孩子广义表 (特殊的表,这种表没有
tag
的 0 或 1 来表示它是原子结点还是表结点) - 普通树 转换成兄弟孩子广义表(特殊的表, 特殊同上)
- 每一个双亲结点最多有两个孩子结点的兄弟孩子广义表 转换成树(特殊的二叉树, 只有叶子结点存数据)
- 一个双亲结点可有任意个孩子结点的兄弟孩子广义表 转换成树(特殊的树,只有叶子结点存数据)
代码功能
- 根据输入的一串字符(字符按树的每一层的结点内容输入),自动建立用兄弟孩子广义表表示的二叉树
- 先序打印树
- 转换成兄弟孩子广义表后,在兄弟孩子广义表的基础上求树的深度
代码附上
// 求树的深度// 兄弟孩子存储结构的树的深度 其实和广义表的兄弟孩子存储结构求深度没有什么区别
// 只不过标识符不一样了, 广义表的标识符是 tag , 而现在 标识符通过指向左孩子的指针来
// 隐式表示 , 若指针为空,那么表示这个是一个 叶子节点(即广义表中的原子) 若不为空,则它还有孩子结点#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 100typedef char Elemtype;
typedef struct node
{Elemtype data;// 指向本结点左孩子结点的指针,和指向本结点下一个兄弟的指针struct node *hp, *tp;
} Node, *Tree;// 初始化二叉树
void Init(Tree *);// 通过输入一串字符来初始化二叉树
void Creat(Tree, char *, int);
void Creat2(Tree, char *, int);
// 输入一串字符并返回
char *Input();// 遍历二叉树
void PrintTree(Tree);// 求深度
int GetDepth(Tree);int main(void)
{Tree tree;Init(&tree);char *str = Input();Creat(tree, str, 0);PrintTree(tree->hp);printf("\n");int depth = GetDepth(tree->hp);printf("%d\n",depth);return 0;
}
// 初始化一个带头结点的二叉树
void Init(Tree *pTree)
{*pTree = (Node *)malloc(sizeof(Node));(*pTree)->data = '0';(*pTree)->hp = NULL;(*pTree)->tp = NULL;
}
char *Input()
{char *s = (char *)malloc(sizeof(char) * MAX);memset(s, '0', sizeof(char) * MAX);gets(s);int len = strlen(s);// 将输入的字符串转化成下标从1开始for (int i = strlen(s); i > 0; i--)s[i] = s[i - 1];return s;
}
// 创建一个二叉树
// 刚开始传的参数是 头指针, 字符数组, 0
void Creat(Tree tree, char *str, int i)
{// 这个函数的利用价值:// 当 i == 0 时,由于传进来的是头指针// 并且头指针指向的是头结点,和别的情况不一样// 所以需要在递归函数外面单独执行一次// 如果根节点就是 '0' 也就代表着这棵树是空的if (str[1] == '0')return;Node *p = (Node *)malloc(sizeof(Node));p->data = str[1];tree->hp = p;Creat2(p, str, 1);
}
void Creat2(Tree tree, char *str, int i)
{tree->data = str[i];// 先解决这个结点的hpif (str[i * 2] == '0' && str[i * 2 + 1] == '0')tree->hp = NULL;else{Node *p = (Node *)malloc(sizeof(Node));tree->hp = p;Creat2(p, str, i * 2);}// 然后解决这个结点的 tpif (str[i + 1] == '0' || i % 2 == 1)tree->tp = NULL;else{Node *q = (Node *)malloc(sizeof(Node));tree->tp = q;Creat2(q, str, i + 1);}
}// 遍历并打印二叉树
// 传进来的是头结点中存的hp
// 即指向根结点的指针,而不是头指针
void PrintTree(Tree tree)
{if (tree == NULL)printf("二叉树为空\n");printf("%c ", tree->data);if (tree->hp)PrintTree(tree->hp);if (tree->tp)PrintTree(tree->tp);
}// 求深度
int GetDepth(Node *T)
{if (!T)return 0;int max = 0;for (Node *temp = T; temp; temp = temp->tp){int depth = GetDepth(temp->hp);if (max < depth)max = depth;}return max + 1;
}
求深度算法(二)
横向纵向都用到了递归,上面那个方法只有纵向用到了递归,横向依靠的是for循环
// 求深度算法 2
int getDep(BitTree T)
{// 空树返回 0if (!T) return 0;// 求当前结点的深度 - 1(既然当前结点存在,其深度必 >= 1)int dep1 = getDep(T->down);// 求当前结点的兄弟结点的深度// 这个语句会在第一次执行的时候不断递归,所以当递归回来到第一次// 执行的函数中的时候, dep2已经是第二个结点以及第二个结点之后的所有结点中// 深度的最大值, 看似这个递归只比较了两个结点,实则该递归比较了一级中的所有结点// 省去了遍历当前层所有结点的操作// 横向纵向同时递归int dep2 = getDep(T->right);// 比较,若当前结点深度 大于 下一个兄弟结点,就返回当前结点深度// 否则 返回下一个兄弟结点的深度if (dep1 + 1 > dep2)return dep1 + 1;return dep2;
}
广义表之树的兄弟孩子表示法相关推荐
- 分层次的非线性结构——树(广义表)05
包含子结构的线性结构,线性表的推广--广义表 广义表的定义 广义表定义 约定:为了区分原子和子表,书写时用大写字母表示子表,用小写字母表示原子. 广义表特性 广义表表示方法 用圆圈和方框分别表示表和单 ...
- 数据结构(C语言)-广义表
广义表 一.广义表的定义和运算 1.广义表的定义 2.广义表的性质 二.广义表的存储 1.头尾表示法 2.孩子兄弟表示法 广义表是线性表的推广,也称为列表(Lists).线性表中的元素仅限于单个数据元 ...
- C#数据结构-广义表和递归
广义表是线性表的推广.定义是:一个广义表是n个元素的一个有限序列.差不多就是线性表元素里面还有线性表,这个表里面的元素称为原子,如果这个原子也是线性表称之为子表.表示为:GL=(a1,a2,a3... ...
- 数据结构与算法(6-1)树的存储(树的双亲表示、树的孩子表示及树的双亲孩子表示)
目录 一.树的双亲表示 存储结构 总代码 二.树的孩子表示 存储结构 总代码 三.树的双亲孩子表示 存储结构 一.树的双亲表示 存储结构 采用结构体数组的形式存储数据. (根结点parent=1:它没 ...
- 广义表的概念及存储表示
文章目录 广义表的概念 广义表的特性 广义表的表头和表尾 广义表的链接存储表示 头尾表示法 扩展线性链表表示法 广义表的概念 广义表的定义:广义表是 n ( n ≥ 0 ) n\ (n≥0) n (n ...
- 输入广义表建立子女兄弟链表示的树
全部代码: #include<iostream> #include<string> #include<vector> #include<stack> # ...
- c语言数据结构大作业,数据结构大作业——树(和广义表)
数据结构大作业--树(和广义表) 以广义表形式输入一棵树,然后以合适的比例将这棵树展示出来 (如何构造一个广义表已经略去) 对于广义表化的树,我们采用的树节点类似二叉链表形式的存储. 首先设计结点内容 ...
- 数据结构c语言——树的三种存储结构(双亲表示法、孩子表示法、兄弟表示法)
在大量的应用中,人们曾使用多种形式的存储结构来表示树.这里,我们介绍3种常用的链表结构. 1.双亲表示法: 假设以一组连续空间存储树的结点,同时在每个结点中附设一个指示器指示其双亲结点在链表中的位置, ...
- 树的概念及存储结构(双亲表示法,孩子表示法,孩子兄弟表示法)
文章目录 一. 树的概念 二. 树的存储结构 (一). 双亲表示法 (二). 孩子表示法 1. 定长结点链表存储结构 2. 孩子链表存储结构 (三). 孩子兄弟表示法 一. 树的概念 树(Tree)是 ...
最新文章
- 利用AOP实现对方法执行时间的统计
- 2020-11-06 Python OpenCV给证件照换底色
- 树莓派安装python3.5_树莓派 | 04 安装基于python3.5的tensorflow,解决python版本不匹配问题...
- hdu 3746 kmp求循环节 下标从1开始
- js让显示层居中且有遮挡层(IE,火狐,Chrome均可)
- XML文件解析 --------------------笔记
- 在word2015中的条形图在灰度的情况下不明显
- Windows10中Edge“嗯...无法访问此页面”,详细信息 DSN名称不存在 问题的解决方案
- 避坑:关于两个HC-05主从一体蓝牙模块互连,连不上问题
- 搭建onedrive个人网盘(详细步骤)
- 工业相机之常见参数|视觉硬件篇
- javascript中的getElementById、getElementsByName、getElementByTagName详解
- DDC EDID 介绍
- mac 使用国内镜像源安装brew
- leetcode 883. 三维形体投影面积(python)
- linux过滤多个手机号的题,正则表达式 多个手机号之间使用英文逗号分隔
- Android APN设置接口
- vue 简介 (MVVM介绍,超详细)
- 数据库工具——mongostat
- 优思学院|六西格玛黑带应如何选择和评估项目?
热门文章
- census变换理解
- LTE系统调试记录13: LTE物理传输资源(1)-帧结构和OFDM符号
- ceph-deploy部署指定版本ceph集群
- win10右下角显示桌面图标消失并且点击左下角Windows按钮或者打开任意文件夹直接全屏无法缩小
- Java 输入一个数字将其转换为汉字,如:102,一百零二
- 名词性从句助动词,be动词,情态动词怎么变?两换一删,很简单!
- 菱形数阵c语言,二年级奥数数阵习题及参考答案.doc-资源下载在线文库www.lddoc.cn...
- SoGua音乐论坛被挂马 音乐小说成黑客攻击目标
- 记录一次Thymeleaf th:inline内联问题
- 图像的几何变换 OpenCV-Python v4.7.0