好大一棵树,任你狂风呼
绿叶中留下多少故事,有乐也有苦
树,是大自然的保护伞,在自然界中扮演者不可替代的角色,而在数据结构的世界中,也有这么一种树,同样具有着非凡的意义,很多复杂的算法,通过树状图可以轻松解决。
今天,忘忧跟大家聊聊数据结构中的树。
什么是树
树不同于之前提到过的链表,队列和栈,他是一种非线性的数据结构,一个节点可以指向n个其他节点,在树中,我们称他们之间的关联关系为父子关系,即当A节点指向B节点和C节点的时候,我们称呼A为B节点或者C节点的父节点,B节点和C节点均为A节点的子节点。
在树中,任意一个节点可以有n多个子节点,这些自己节点又同样可以拥有自己的子节点。
树中的相关名字解释
- 根节点:也称为root节点,树结构中最上层的节点,即没有父节点的节点。在一个非空的树状结构中,根节点有且至多有一个,他是除自身外所有节点的直接或间接父节点。
- 叶子节点:所有没有子节点的节点,都成为叶子节点,在一个非空的树状结构中,叶子节点的数量总是大于等于一个。
- 非叶子节点:同叶子节点相反,所有拥有子节点的节点都属于非叶子节点。
关于二叉树
二叉树作为一种比较特殊的树,他规定每个节点最多有两个子节点,且他的子节点有左右之分,不可以随意颠倒。
二叉树的遍历
关于二叉树节点的定义如下:
/**
* algorithm
* @author 忘忧
* @date 2020/3/15
* 二叉树节点定义
*/
public class TreeNode {
/**
* 节点存储的值
*/
int val;
/**
* 左子树
*/
TreeNode left;
/**
* 右子树
*/
TreeNode right;
public TreeNode(int val) {
this.val = val;
}
public int getVal() {
return val;
}
public void setVal(int val) {
this.val = val;
}
public TreeNode getLeft() {
return left;
}
public void setLeft(TreeNode left) {
this.left = left;
}
public TreeNode getRight() {
return right;
}
public void setRight(TreeNode right) {
this.right = right;
}
}
前序遍历
所谓的前,是指父节点在前,遍历时先取得父节点的值,然后再对该节点下的左子树进行前序遍历,左子树遍历完成之后,再对右子树遍历。
前序遍历结果为:1245367
前序遍历代码实现如下:
/**
* 前序遍历
*/
public static void preErgodic(TreeNode treeNode){
if(treeNode == null){
return;
}
//输出当前节点的值
System.out.print(treeNode.getVal());
//前序遍历左子树
preErgodic(treeNode.getLeft());
//前序遍历右子树
preErgodic(treeNode.getRight());
}
中序遍历
同理,中序遍历的中,也是指父节点输出在中,左子树优先遍历,左子树遍历完成之后,输出当前节点,然后再中序遍历右子树。
中序遍历的结果为:4251637
中序遍历的代码实现如下:
/**
* 中序遍历
*/
public static void middleErgodic(TreeNode treeNode){
if(treeNode == null){
return;
}
//先中序遍历左子树
middleErgodic(treeNode.getLeft());
//输出当前节点的值
System.out.print(treeNode.getVal());
//最后中序遍历右子树
middleErgodic(treeNode.getRight());
}
后序遍历
将父节点的输出放在最后,先后续遍历左子树,再后序遍历右子树,最后输出本身,后序遍历中最后输出的元素永远是根节点。
后序遍历的结果为:4526731
后续遍历的代码实现如下:
/**
* 后序遍历
*/
public static void lastErgodic(TreeNode treeNode){
if(treeNode == null){
return;
}
lastErgodic(treeNode.getLeft());
lastErgodic(treeNode.getRight());
System.out.print(treeNode.getVal());
}
特殊的二叉树定义
- 满二叉树: 一个二叉树,如果每一层的节点个数都达到最大值,则为满二叉树
- 完全二叉树: 一个二叉树,除了最后一层外,其他层的节点个数都达到最大值,且最后一层的节点为从左侧起的连续节点,则为完全二叉树,满二叉树属于一种特殊的完全二叉树。
- 二叉排序树: 按照中序遍历出来的结果为递增,则为二叉排序树(即对每一个非叶子节点,左子树的所有节点小于当前节点,右子树的所有节点大于当前节点)
- 二叉平衡树: 对于所有非叶子节点,他的左右子树的深度要么相同,要么相差1,则为二叉平衡树
树的变种
关于树的一些变种,例如红黑树,B树等,在此就不做深入的讨论了,后续在解析算法的时候,再继续讲解。
山重水复疑无路,柳暗花明又一村