文章目录
- 1.认识
- 1.1树的特点:
- 1.2 树的术语
- 1.3 树的表示
- 2.二叉树
- 2.1二叉树的几个重要特性:
- 2.2特殊的二叉树
- 2.3二叉树的存储方式
1.认识
树也是一种很常用的数据结构
树是一种重要的非线性数据结构,直观地看,它是数据元素(在树中称为结点)按分支关系组织起来的结构,很象自然界中的树那样。
1.1树的特点:
- 每个结点有零个或多个子结点
- 没有父结点的结点称为根结点
- 每一个非根结点有且只有一个父结点
- 除了根结点外,每个子结点可以分为多个不相交的子树
树结构是一种非线性存储结构,存储的是具有“一对多”关系的数据元素的集合。
1.2 树的术语
关于树的术语我在这里列出,有助于下面学习:
- 节点的度:一个节点含有的子树的个数称为该节点的度
- 树的度:一棵树中,最大的节点的度称为树的度;
- 叶节点: 度为0的节点(叶子节点)
- 父节点:有子树的节点是其子树的根节点的父节点
- 子节点:若A结点是B结点的父结点,则称B结点是A结点的子结点;子结点也称孩子结点。
- 兄弟节点:具有同一父结点的各结点彼此是兄弟结点
- 结点的层次:规定根结点在1层,其它任一结点的层数是其父结点的层数加1
- 树的深度:树中所有节点中的最大层数为树的深度
1.3 树的表示
树的表示可以使用多种形式,我们这里介绍一下常规表示法与儿子兄弟表示法。
我们将下图的树分别使用两种方式表示。
常规表示法:
这是我们常规情况下使用的树结构表示方法。可以看到每个节点都有各自的引用。
我们用A节点来举例表示,代码如下:
Node{
this.data=data
this.left=B
this.middle=C
this.right=D
}
这样我们可以很简单的理解,但是问题来了,我们怎样表示B和C呢。很显然他们的结构是不一样的。这样就造成了混乱。
这时就引出了我们的儿子兄弟表示法
儿子兄弟表示法:
顾名思义,我们通过目标的左子节点和兄弟节点可以表示一棵树。如下图所示
我们试试使用代码表示A节点和B节点:
A节点:
Node{
this.data=data
this.leftchild=B
this.brother=null
}
B节点:
Node{
this.data=data
this.leftchild=E
this.brother=C
}
我们将这种图旋转后可以得到下面的结果:
是不是这种像极了一个二叉树,对的。
因此我们得出结论:所有的树本质上都可以使用二叉树模拟出来
接下来我们来学习二叉树。
2.二叉树
如果一个树的每个节点最多只能有两个子节点,这样的树就称为“二叉树”.
概念:
二叉树的定义:二叉树可以为空 ,也就是没有节点;若不为空,则它是由根节点和称为左子树和右子树的两个不相交的二叉树组成。
二叉树有五种形态:
2.1二叉树的几个重要特性:
- 第n层的最大结点数:2^(n-1)
- 深度为k的二叉树最大节点总数:2^n-1
- 对于任何一个非空二叉树,若n0表示叶节点的个数,n1表示度为2的非叶节点个数,那么二者满足关系n0=n1+1
这三个特性用我们的数学公式也可以推导出来
2.2特殊的二叉树
特殊的二叉树由完美二叉树与完全二叉树
完美二叉树
除了最后一层节点外,每层节点都有2个结点,就构成了完美二叉树
完全二叉树
除二叉树最后一层外, 其他各层的节点数都达到最大个数,并且最后一层结点应该从左向右连续存在,只缺右侧。
2.3二叉树的存储方式
关于二叉树的存储方式我们通常使用链表来实现。为什么不能使用使用数组呢?
其实数组可以很好的实现完全二叉树。我们想一想完全二叉树的解构,处最后一层外其他各层结点数都达到最大数因此我们可以很好的使用数组表示他们的位置。但是当我们遇到非完全二叉树呢?
如果依然使用数组表示必然会造成数组空间的浪费。
所以我们二叉树的存储方式使用链表来进行