树的基本概念及表示方法
关于树的基本概念及表示方法
- 概念性的东西
- 树的存储结构
- 双亲表示法
- 孩子表示法
- `malloc函数用法`
- 参考代码
- 孩子兄弟表示法
概念性的东西
- 树的定义:是n(n >= 0)个结点的有限集。当n = 0时称为空树,在任意一颗非空树中:
(1)有且仅有一个
特定的称为根的结点。
(2)当n>1时,其余结点可分为m(m > 0)个互不相交的
有限集T1,T2…Tm,其中每一个集合本身又是一棵树,并且称为根的子树
。 - 关于度:
(1) 结点拥有的子树数称为结点的度,
(2) 树的度:取树内各结点的度的最大值。
(3)度为0的结点称为叶结点或终端结点
(4) 度不为0的结点称为分支结点或非终端结点,除根节点外,分支结点也称为内部结点。 - 结点间的关系:
(1)结点的子树的根称为结点的孩子,相应的,该结点称为孩子的双亲,同一双亲的孩子间称为兄弟(Sibling)
(2)结点的祖先是从根到该结点所经分支上的所有结点。 - 结点的层次
(1)结点的层次从根开始定义起,根为第一层,根的孩子为第二层
(2)其双亲在同一层的结点互为堂兄弟
(3)树中结点的最大层次称为树的深度或高度 - 有序树:将树中结点的各子树看成从左至右是有次序的、不能互换的树。(反之,为无序树)
- 森林:是m(m >= 0)颗互不相交的树的集合。对树中每个结点而言,其子树的集合即为森林。
树的存储结构
我们需要考虑到双亲、孩子、兄弟间的关系。
在这里我们用三种方法来尝试存储下面这个普通树。
双亲表示法
采用顺序表(即数组)存储,核心思想:顺序存储各个节点的同时,给各个节点附加一个记录其父节点位置的变量
注:根节点没有父节点,根节点记录父节点的位置的变量通常设为-1.
下列代码的功能为:输入这棵树中结点的个数(10), 各结点的值,及其双亲在数组中的下标。输入查询的结点值,输出他的父节点及父节点存储位置的下标。
代码效果:
#include <iostream>
#include <algorithm>
#define MAX_SIZE 20
using namespace std;typedef struct Snode{ //结点的结构char data; //树中结点的数据类型为charint parent;//结点的父节点在数组中的位置下标}PNode;typedef struct{PNode tnode[MAX_SIZE]; //存放树中的所有结点int n; //根的位置下标和结点数
}PTree;PTree InitPNode(PTree tree){ //按照上述表 存储这颗树int i, j;char ch;printf("请输入结点个数:");scanf("%d", &(tree.n));printf("请输入各结点的值及其双亲位于数组中的位置下标:\n");getchar();for(int i = 0; i < tree.n; i ++){scanf("%c %d", &ch, &j);getchar();tree.tnode[i].data = ch;tree.tnode[i].parent = j;}return tree;
}
void FindParent(PTree tree){char a;int flag = 0;printf("请输入要查询的结点值:");scanf("%c", &a);getchar();for(int i = 0; i < tree.n; i ++){if(tree.tnode[i].data == a){flag = 1;int ad = tree.tnode[i].parent;printf("%c 的父节点为 %c, 存储位置下标为 %d\n", a, tree.tnode[ad], ad);break;}}if(flag == 0) cout <<"树中无此节点" << endl;}int main(void){PTree tree;tree = InitPNode(tree);int n = 4;while(n --){FindParent(tree);}return 0;
}
孩子表示法
【顺序表 + 链表】
在这里我们仅用代码实现相对节省资源的一种方法思路:
从树的根节点开始,使用顺序表依次存储树中的各个节点,给每个结点配备一个链表来存储孩子节点位于顺序表中的位置。
malloc函数用法
- C中,该函数在
<stdlib.h>
中 void *malloc(size_t, size)
size为内存块的大小,以字节为单位。- 返回一个指针,指向已分配大小的内存,如果请求失败,返回NULL
实例演示:
参考代码
其实对于这个代码吧,,涉及到了指针,又是纯C语言实现的,个人认为,我们完全可以用STL代替。比如字符串中的find函数, queue, vector等,自己也还没亲手敲过,但下列代码中的结构体嵌套还是很新鲜的。。
#include<stdio.h>
#include<stdlib.h>
#define MAX_SIZE 20
#define TElemType char
//孩子表示法
typedef struct CTNode{int child;//链表中每个结点存储的不是数据本身,而是数据在数组中存储的位置下标struct CTNode * next;
}ChildPtr;
typedef struct {TElemType data;//结点的数据类型ChildPtr* firstchild;//孩子链表的头指针
}CTBox;
typedef struct{CTBox nodes[MAX_SIZE];//存储结点的数组int n,r;//结点数量和树根的位置
}CTree;
//孩子表示法存储普通树
CTree initTree(CTree tree){printf("输入节点数量:\n");scanf("%d",&(tree.n));for(int i=0;i<tree.n;i++){printf("输入第 %d 个节点的值:\n",i+1);fflush(stdin);scanf("%c",&(tree.nodes[i].data));tree.nodes[i].firstchild=(ChildPtr*)malloc(sizeof(ChildPtr));tree.nodes[i].firstchild->next=NULL;printf("输入节点 %c 的孩子节点数量:\n",tree.nodes[i].data);int Num;scanf("%d",&Num);if(Num!=0){ChildPtr * p = tree.nodes[i].firstchild;for(int j = 0 ;j<Num;j++){ChildPtr * newEle=(ChildPtr*)malloc(sizeof(ChildPtr));newEle->next=NULL;printf("输入第 %d 个孩子节点在顺序表中的位置",j+1);scanf("%d",&(newEle->child));p->next= newEle;p=p->next;}}}return tree;
}
void findKids(CTree tree,char a){int hasKids=0;for(int i=0;i<tree.n;i++){if(tree.nodes[i].data==a){ChildPtr * p=tree.nodes[i].firstchild->next;while(p){hasKids = 1;printf("%c ",tree.nodes[p->child].data);p=p->next;}break;}}if(hasKids==0){printf("此节点为叶子节点");}
}
int main()
{CTree tree;tree = initTree(tree);//默认数根节点位于数组notes[0]处tree.r=0;printf("找出节点 F 的所有孩子节点:");findKids(tree,'F');return 0;
}
孩子兄弟表示法
通过孩子兄弟表示法,任意一棵普通树都可以相应转化为一棵二叉树,换句话说,任意一棵普通树都有唯一的一棵二叉树于其对应。
在此我就先不敲这个代码了,后续的二叉树文章中,再说再说。
树的基本概念及表示方法相关推荐
- 数据结构(3) 第三天 栈的应用:就近匹配/中缀表达式转后缀表达式 、树/二叉树的概念、二叉树的递归与非递归遍历(DLR LDR LRD)、递归求叶子节点数目/二叉树高度/二叉树拷贝和释放...
01 上节课回顾 受限的线性表 栈和队列的链式存储其实就是链表 但是不能任意操作 所以叫受限的线性表 02 栈的应用_就近匹配 案例1就近匹配: #include <stdio.h> in ...
- 树的基本概念和遍历规则 数据结构和算法 二叉树遍历(前序、中序、后序、层次、深度优先、广度优先遍历)
zsychanpin 博客园 首页 新随笔 联系 订阅 管理 树的基本概念和遍历规则 树的递归定义 树是n(n>0)个结点的有限集,这个集合满足下面条件: ⑴有且仅有一个结点没有前驱 ...
- 计算机之树的概念,2019考研计算机数据结构考点:树的基本概念
根据历年考试经验,数据结构所占分值为45分,所占分值比重较大;而且数据结构部分的知识比较难于理解,为方便考生更好地复习计算机专业课,新东方在线整理了考研计算机数据结构的有关内容,以供大家参考,希望对大 ...
- 树的基本概念以及java实现二叉树(二)
前言 本文是我在学习了树后作的总结文章,接上篇文章,本节大致可以总结为: 二叉树的遍历与实现(递归和非递归) 获取二叉树的高度和度 创建一棵二叉树 其他应用(层序遍历,复制二叉树,判断二叉树是否相等) ...
- 树的基本概念以及java实现二叉树(一)
前言 作为一个程序员,要了解最基本的数据结构的.本文是我在学习了树后作的总结文章,本节大致可以总结为: 什么是树 树的基本性质(专有名词) 什么是二叉树 二叉树的基本性质 二叉树的存储结构 文章传送门 ...
- 图与网络模型:经典问题、基本概念、表示方法、连通图
图&网络系列博文: [1]图与网络模型及方法:图与网络的基本概念 [2]图&网络模型应用-最短路径问题 [3]树:基本概念与最小生成树 [4]匹配问题: 匈牙利算法 .最优指派.相等子 ...
- 数据结构笔记——树的基本概念
树的定义 之前一直介绍的是一对一的线性结构,可现实中还有多一对多的情况需要处理,这就是今天要介绍的一对多的数据结构--树. 树(Tree):是n(n>=0)个结点的有限集.n=0时称为空树.在任 ...
- 后缀树系列一:概念以及实现原理( the Ukkonen algorithm)
首先说明一下后缀树系列一共会有三篇文章,本文先介绍基本概念以及如何线性时间内构件后缀树,第二篇文章会详细介绍怎么实现后缀树(包含实现代码),第三篇会着重谈一谈后缀树的应用. 本文分为三个部分, 首先介 ...
- php easyui tree 结构,EasyUI Tree树组件无限循环的解决方法
在学习jquery easyui的tree组件的时候,在url为链接地址的时,发现如果最后一个节点的state为closed时,未节点显示为文件夹,单击会重新加载动态(Url:链接地址)形成无限循环. ...
- IOS学习笔记(九)之UIAlertView(警告视图)和UIActionSheet(操作表视图)基本概念和使用方法...
IOS学习笔记(九)之UIAlertView(警告视图)和UIActionSheet(操作表视图)基本概念和使用方法 Author:hmjiangqq Email:jiangqqlmj@163.com ...
最新文章
- [数据库] Oracle单表查询总数及百分比和数据横向纵向连接
- Linxu的常用命令
- CRM_ORGMAN_CHECK_OW
- 吴恩达机器学习(二)多元线性回归(假设、代价、梯度、特征缩放、多项式)
- Python 数据结构与算法——归并排序
- etl构建数据仓库五步法_构建数据仓库五步法
- sql 如何把查询得到的结果如何放入一个新表中
- 视频、网络传输速率科普
- 贝叶斯公式的直观理解(先验概率/后验概率)
- tl494cn逆变器电路图_基于TL494CN的车载逆变器电路设计
- yum源的三种配置方式
- C语言复习——投票问题——动态数组(2021.11.20)
- 安装mysql staring server 失败 已经成功决解。
- HttpClient4.5.6设置代理以及代理验证(用户名和密码)
- the little scheme 代码
- 真实的90后创业者是怎样的状态?
- prometheus图形界面的基本监控配置
- STM32 FLASH的写入与读取
- seque Pro 每次打开都会提示错误
- sanitize php,PHP -Sanitize数组的值
热门文章
- win10防火墙_怎么关闭防火墙
- PostgreSQL数据库部署之 :PostgreSQL pgadmin4 the application server could not be contacted
- Java 视频网盘分享
- 一文搞懂vim复制粘贴
- 腾讯视频显示网络连接服务器失败怎么办,腾讯视频不能投屏怎么回事 腾讯视频无法投屏的解决方法...
- 如何评价腾讯云游戏平台 START ?
- IOS版应用商店应用源码
- 什么是 HTTPS 的证书信任链?自己给自己发行不行?
- Google抢Waze:除了地图还有什么?
- 《The Elder Scrolls V: Skyrim》百般冷门却强力职业