树和二叉树的概念及结构定义
前言
二叉树是一种树形数据结构,在日常生活中也有广泛的运用,比如windows操作系统中文件夹的目录结构可以看成一种运用。
一、树的基本概念及代码层面如何定义
1、树的概念
一个普通的树如下图所示:
树中“度”的概念如下:
- 节点的度:可以看到①节点的度为4,②节点的度为1,③节点的度为2,④节点的度为1,⑤节点的度为0,即度代表当前节点子树的个数。
- 树的度:所有节点中度的最大值,上面这幅图的树的度就是节点①的度。
- 叶子节点的度都为0。
2、代码层面树如何定义
概念介绍完了,当我们程序员看到这张图的时候,我们脑海里首先想到的应该是如何从代码层面来构造这棵树?比如树的定义,树中节点的定义?只有将树的结构清晰明白的定义好,才有利于后期的编程。
public class Tree<E>{
//代表节点数量
int size;
//代表根节点
Node<E> root;
static class Node<E>{
//节点中存储什么数据类型,这边使用的是泛型
E element;
//当前节点的子节点应该用什么存储,可以用集合进行存储
List<Node> nexts;
//这边也可以记录当前节点的父节点
Node<E> parent;
}
}
面向对象的思想讲起来比较简单,但是想通过这种思想来解决实际问题,还需要多加练习,比如上面这颗树,我们单独将“树”这个整体拿出来做一个对象,将树中的节点作为另一个对象,这样的设计就比较清晰。
到后面的二叉搜索树,AVL树中,可以针对Node节点和Tree树这个整体提供不同的方法,比如Node节点中可以提供计算当前节点高度的方法,Tree树中可以提供以变量root为根节点的树是不是完全二叉树的判断方法、以及前中后序遍历等方法。
二、二叉树的基本概念及代码层面如何定义
1、二叉树的概念
- 每个节点的度最大为2,(即最多拥有2棵子树)。
- 即使某个节点只有一颗子树,也要区分左子树还是右子树。
二叉树如下图所示:
2、代码层面二叉树如何定义
二叉树的数据结构如何定义呢?要以面向对象的思想来思考,二叉树中的节点是对象,那么我们可以将其进行单独封装,树本身也是对象,我们也将其单独封装,只有在编程过程中不断思考,面向对象的设计方法才会显得愈发深刻。
public class Tree<E>{
//二叉树的节点数量
int size;
//二叉树的根节点
Node<E> root;
static class Node<E>{
//二叉树节点中存储的元素
E element;
//左子树
Node<E> left;
//右子树
Node<E> right;
//父节点
Node<E> parent;
}
}
3、二叉树的性质
- 非空二叉树的第i层,最多有 2 i − 1 2^{i-1} 2i−1个节点(i>=1);
- 在高度为h的二叉树上最多有 2 h − 1 2^h-1 2h−1个节点(h>=1);
- 对于任何一棵非空二叉树,如果叶子节点个数为n0,度为2的节点个数为n2,则有n0=n2+1;
- 假设度为1的节点个数为n1,那么二叉树的节点总数n=n0+n1+n2;
- 二叉树的边数T=n1+2*n2=n1+n2+n2=n-n0+n0-1=n-1;即等于总节点数n-1;
三、几种特殊的二叉树
1、真二叉树
真二叉树定义:所有节点的度要么为0要么为2。如下图所示,
左图是真二叉树,除了叶子节点度为0,其余节点度为2,没有度为1的节点。
右图是非真二叉树,③节点的度为1。
2、满二叉树
满二叉树定义及图例
定义:最后一层节点的度为0,其余节点的度为2。图例如下所示:
满二叉树的性质
性质:①在同样高度的二叉树中,满二叉树的叶子结点数量最多、总结点数量最多。
②满二叉树一定是真二叉树,真二叉树不一定是满二叉树。
③假设满二叉树的高度为h(h>=1),那么第i层的节点数量:
2
i
−
1
2^{i-1}
2i−1
,叶子节点数量
2
h
−
1
2^{h-1}
2h−1,总节点数量n=
2
h
−
1
2^h-1
2h−1=
2
0
2^0
20+
2
1
2^1
21+
2
2
2^2
22+…+
2
h
−
1
2^{h-1}
2h−1。
3、完全二叉树
完全二叉树的定义及图例
定义:对节点从上至下、从左至右开始编号,其所有编号都能与相同高度的满二叉树中的编号对应。图例如下所示:
特点:
- 叶子节点只会出现在最后2层,最后一层的叶子节点都靠左对齐。
- 完全二叉树从根节点至倒数第二层是一颗满二叉树。
- 满二叉树一定是完全二叉树,完全二叉树不一定是满二叉树。
完全二叉树的性质
- 度为1的节点只有左子树。
- 度为1的节点要么是1个,要么是0个。
- 同样节点数量的二叉树,完全二叉树的高度最小。
- 假设完全二叉树的高度为h(h>=1),那么这颗完全二叉树至少有 2 h − 1 2^{h-1} 2h−1个节点( 2 0 2^0 20+ 2 1 2^1 21+ 2 2 2^2 22+…+ 2 h − 2 2^{h-2} 2h−2+1),最多有 2 h − 1 2^h-1 2h−1个节点,也就是满二叉树。
- 一颗有n个节点的完全二叉树(n>0),从上到下,从左到右对节点从1开始进行编号,对任意第i个节点有如下特点:
①如果i=1,它是根节点。
②如果i>1,它的父节点编号为floor(i/2),即(i/2)向下取整。
③如果2i<=n,它的左子节点编号为2i。
④如果2i>n,它没有子左节点。
⑤如果2i+1<=n,它的右子节点编号为2i+1。
⑥如果2i+1>n,它没有子右节点。
性质5要着重掌握,因为堆排序就用到了完全二叉树。