目录
提到树,首先先要介绍结点:
结点是数据结构中的基础。他是够称复杂数据结构的基本组成单位。
树
介绍:是n(n>=0)个结点的有限集,n=0,称为空树。
在任意的非空树里:
1.有且仅有一个特定的称为根节点
2.当n>1时。其余结点可分为m个互不相交的有限集。
定义树的时候
1.根节点是唯一的,不能存在多个根节点
2.子树的个数,没有限制,但是他们一定是互不相交的
树的定义中,使用了递归的方式。递归在树的学习过程中起着重要的作用
结点的度:
结点拥有子结点的数量称为结点的度
结点之间的关系:
结点的子树的根节点称为该结点的孩子结点。
相应该结点称为孩子结点的父结点(双亲结点)
树的深度:
树里的结点的最大层数称为树的深度或高度。
二叉树:
二叉树是一种树形结构,具体展示为:
二叉树是n个结点的有限集合,如果n=0就成为空二叉树。
二叉树的特点:
1.每个结点最多只有两颗子树,所以二叉树中不存在度大于2的结点。
2.左子树和右子树他是有顺序的,而且次序不能任意颠倒。
3.即使树中某个结点只有一颗子树。也要区分他是左子树还是右子树
二叉树的性质:
1.在二叉树中第i层上最多有2^(i-1)个结点(i>=1);
2.二叉树中如果深度为k;那么最多有2^k-1个结点;
3.n0=n2+1,n0表示度数为0的结点,n2表示度数为2的结点数
4.完全二叉树中,具有n个结点的完全二叉树他的深度为,[Log2n]+1;其中log2n向下取整
5.若含n个结点的完全二叉树从上到下且从左到右进行1至n的编号,
则对完全二叉树中任意一个编号为i的结点有如下特性:
(1)若i=1,则该结点是二叉树的根,无父节点,否则,编号为i/2的结点为父节点(2)若2i>n,则该节点他无左孩子结点。否则编号为2i的结点为其左孩子结点
(3)若2i+1>n,则该节点无右孩子结点,否则,编号为2i+1的结点为右孩子结点。
斜数:
所有的结点都只有左子树的二叉树,叫左斜数。
所有的结点都只有右子树的二叉树,叫右斜数。
满二叉树:
在一棵二叉树中,如果所有分支节点都存在左子树和右子树,并且所有的叶子都在同一层上,这样的二叉树叫做满二叉树
特点:
1.叶子只能出现在下一层。
2.非叶子结点的度一定是2
3.在同样的深度的二叉树中,满二叉树的结点的个数最多,叶子数也最多。
完全二叉树:
对一颗具有n个结点的二叉树按层编号,如果编号为i(1<=i<=n)的结点与同样深度的满二叉树中编号为i的结点相同。这颗二叉树就是完全二叉树。
二叉树的存储结构:
1.顺序存储
使用一维数组存储二叉树中的结点,并且结点的位置,就是数组的的下标索引。
如果当二叉树为完全二叉树时,结点树刚好填满数组。
如果二叉树不是完全二叉树,采用顺序存储,顺序存储结构中已经出现了空间浪费的情况。
比如右斜数极端情况,采用顺序存储的方式是十分浪费空间。
顺序存储只适用于完全二叉树。
2.二叉链表
顺序存储不能满足二叉树的存储要求,采用链式存储。
二叉树的每个结点都有两个孩子。
可以将结点数据结构定义成一个数据和两个指针域。
**二叉树的遍历**
二叉树的遍历也是从根节点出发,按照某种次序依次访问二叉树中的所有结点,使得每个结点被访问一次,且仅被访问一次。
二叉树的访问次序可以分为四种:
前序遍历:
顺序为:(ABDECFG)
从二叉树的根结点出发,当第一次到达结点时就输出结点数据,按照先向左再向右的方向访问。(根---左---右)
中序遍历:
顺序为:(DBEAFCG)
访问顺序:先左子树,然后根结点,然后右子树(左---根---右)
后序遍历:
顺序为:(DEBFGCA)
访问顺序:先左子树,然后根结点,然后右子树(左---右---根)
层次遍历:
就是按照树的层次自上而下,自左而右的遍历二叉树(ABCDEFG)
代码实现:
class TreeNode<T>{
T data;//数据本身
TreeNode left;//左孩子
TreeNode right;//右孩子
public TreeNode(T data){
this.data=data;
}
}
前序遍历:
public static void preorder(TreeNode root){
if(root==null){
return;
}
System.out.println(root.data);
//运用递归
preorder(root.left);
preorder(root.right);
}
中序遍历:
public static void inorder(TreeNode root){
if(root==null){
return;
}
inorder(root.left);
System.out.println(root.data);
inorder(root.right);
}
后序遍历:
public static void postorder(TreeNode root){
if(root==null){
return;
}
postorder(root.left);
postorder(root.right);
System.out.println(root.data);
}
测试类:
public class Test01 {
public static void main(String[] args) {
TreeNode<Integer> root = new TreeNode<>(1);
root.left=new TreeNode(2);
root.right=new TreeNode(3);
root.left.left=new TreeNode(4);
root.left.right=new TreeNode(5);
root.right.left=new TreeNode(6);
root.right.right=new TreeNode(7);
TreeNode.preorder(root);
System.out.println("--------");
TreeNode.inorder(root);
System.out.println("--------");
TreeNode.postorder(root);
System.out.println("--------");
}
}
运行结果:
其他的树分类:
(粗略介绍一下)
1.二叉查找树(搜索树/排序树)
(1)若左子树不为空,左子树的所有的值小于它的根节点的值
(2)若右子树不为空,右子树的所有的值大于它的根节点的值
(3)左右子树也是一个二叉查找树
(4)没有键值相等的点。
2.平衡二叉树(AVL树)
含有相同结点的二叉树的不同形态。找出一个查找平均长度最小的一颗二叉查找树
(1)要么是一颗空树,要么其根节点的左右子树的深度之差绝对值不超过1.
(2)左右子树都是平衡二叉树
(3)二叉树结点的平衡因子定义为该结点的左子树的深度减去右子树的深度
平衡因子=左子树的深度-右子树的深度。
3.红黑树
自平衡的二叉树。又增加了一个颜色的属性。
结点的颜色只能是红色或者黑色
(1)根节点只能是黑色
(2)红黑树中,所有的叶子结点后面再街上左右两个空结点,保持算法的一致性。所有的空结点也是黑色
(3)其他的结点要么是黑色,要么是红色,红色结点的父节点和左右孩子结点都是黑色
(4)在任意一颗子树中,从根节点向下走到空结点的路径上所经历的黑色结点数是相同的。
4.B-树(B树)
B-树是一种平衡多路查找树,它在文件系统中很有用,一颗m阶B-树
(1)树中每个子节点至多有m颗子树
(2)若根节点不是叶子结点,则至少有两颗子树
(3)除根节点外所有非终端结点至少有【m/2】棵子树
(4)每个结点的信息结构(A0,K1,A1,K2......Kn.An),其中n表示关键字个数 * k为关键字,A为指针
(5)所有的叶子结点都出现在同一层次上,且不带任何信息。
5.B+树
B-树和B+树,后序在数据库才会重点应用!!!
现在就不过多介绍了(主要是我也没怎么看这些树,嘻嘻)