package study;
/*
- 树结构
- 为什么会有树结构?
- 存储方式:数组、链式存储
- 数组可以通过下标来定位数据(检索容易),但是增删数组空间困难,增删会使底层创建新的数组再进行增删数据。
- 某些集合的底层维护了Object数组(对象数组)。本质是不是数组?集合底层数组按比例扩容(扩容导致效率低)。
- 链式存储的增删容易,检索不易。
- 所以需要树来提高存储修改效率。
- 为什么树会提高存储修改的效率?
- 二叉树的结构:节点和下两个数据,小的数据放在节点左边,大的数据放在节点右边。查找的时候对树查找,就类似于二分查找,增删就是链式增删。
- 当然树有很多种。
- 树的术语有哪些?
- 节点,根节点,父节点,子节点。
- 叶子节点:没有子节点的节点。
- 节点的权:可以简单理解为节点里面存放的值。
- 路径:从根节点找到该节点的路线。
- 层:树看着像楼房,就是房子的层呀。
- 子树:就是随意挑一个节点和该节点下面构成的树可以称为是上面相连节点子树。
- 树的高度:就是树的最大层数。
- 森林:多颗子树构成森林。
- 什么是二叉树?
- 树的每个节点最多有两个子节点。
- 什么是满二叉树?
- 二叉树的所有叶子节点都在最后一层且树的所有节点总和为2^n-1,n为层数。
- 二叉树的前序、后序、中序遍历。看父节点在遍历中的顺序。
- 前序:先父节点后左节点再后是右节点的遍历。
- 中序:先左节点后父节点再后是右节点的遍历。
- 后序:先左节点后右节点再后是父节点的遍历。
- 不管如何遍历都要先root节点。
*/
/*
- 创建二叉树
- 遍历二叉树:递归。
*/
public class SiKaoZhiHui {
// 欲速则不达
// 学代码得写
public static void main(String[] args) {
// 创建二叉树
BinaryTree binaryTree = new BinaryTree();
// 创建二叉树所需要的节点
HeroNode heroNode1 = new HeroNode(1, "宋江");
HeroNode heroNode2 = new HeroNode(2, "吴用");
HeroNode heroNode3 = new HeroNode(3, "卢俊义");
HeroNode heroNode4 = new HeroNode(4, "林冲");
//将节点添加子节点
heroNode1.setLeft(heroNode2);
heroNode1.setRight(heroNode3);
heroNode3.setRight(heroNode4);
//将根节点给二叉树对象构成二叉树,构成树可以使用递归。
binaryTree.setRoot(heroNode1);
System.out.println("---------------");
//对二叉树进行前序遍历
binaryTree.preOrder();
System.out.println("---------------");
//对二叉树进行中序遍历
binaryTree.infixOrder();
System.out.println("---------------");
//对二叉树进行后序遍历
binaryTree.postOrder();
System.out.println("---------------");
}
}
// 创建关于英雄hero的节点
class HeroNode {
private int no;// 编号
private String name;
private HeroNode left;
private HeroNode right;
public HeroNode() {
super();
}
@Override
public String toString() {
return "HeroNode [no=" + no + ", name=" + name + "]";
}
public HeroNode(int no, String name) {
super();
this.no = no;
this.name = name;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public HeroNode getLeft() {
return left;
}
public void setLeft(HeroNode left) {
this.left = left;
}
public HeroNode getRight() {
return right;
}
public void setRight(HeroNode right) {
this.right = right;
}
// 前序遍历的方法
public void preOrder() {
System.out.println(this);// 先打印父节点。
// 递归向左子树前序遍历
if (this.left != null) {
this.left.preOrder();
}
// 递归向右子树前序遍历
if (this.right != null) {
this.right.preOrder();
}
}
// 中序遍历的方法
public void infixOrder() {
// 递归向左子树中序遍历
if (this.left != null) {
this.left.infixOrder();
}
// 打印父节点
System.out.println(this);
// 递归向右子树中序遍历
if (this.right != null) {
this.right.infixOrder();
}
}
// 后序遍历
public void postOrder() {
// 递归向左子树后序遍历
if (this.left != null) {
this.left.postOrder();
}
// 递归向右子树后序遍历
if (this.right != null) {
this.right.postOrder();
}
// 打印父节点
System.out.println(this);
}
}
// 定义二叉树
class BinaryTree {
private HeroNode root;
public void setRoot(HeroNode root) {
this.root = root;
}
// 前序遍历,所有的遍历都是从root开始的所以用root调用节点里面的前序遍历方法。
public void preOrder() {
if (this.root != null) {
this.root.preOrder();
;
} else {
System.out.println("二叉树为空");
}
}
// 中序遍历
public void infixOrder() {
if (this.root != null) {
this.root.infixOrder();
} else {
System.out.println("二叉树为空");
}
}
// 后序遍历
public void postOrder() {
if (this.root != null) {
this.root.postOrder();
} else {
System.out.println("二叉树为空");
}
}
}