package com.mldn.BinaryTree;
import java.util.ArrayList;
import java.util.Arrays;
/**
* 时间:2019年7月25日 项目名称:MyProject02 二叉树的添加和遍历
*
* @author Administrator
*/
class Tree {
private Node root; // 根节点
private ArrayList<Node> result = new ArrayList<Node>(); // 存放结果
private int floor = 1;
private ArrayList<Integer> floors = new ArrayList<Integer>(); //存放楼层
private int temp = -1 ;
/**
* 插入函数用到的方法
*
* @param num
*/
public void add(int num) {
Node newNode = new Node();
newNode.setNum(num); // 将数字放到节点里面
if (root == null) { // 如果根节点为空 将这个节点设置为根节点
this.root = newNode;
} else { // 有根节点
insert(newNode, root); // 用向树里面添加
}
}
/**
* 将节点插入二叉树
*
* @param num 要插入的节点
* @param parentNode 父节点
* @return boolean 如果小就让左节点 当父节点 如果大就让右节点 当父节点 递归 插入成功true 失败false
*/
private boolean insert(Node src, Node parentNode) {
if (src.getNum() < parentNode.getNum()) { // 如果小于 往左插
if (parentNode.getLeftChild() == null) { // 如果等于空
parentNode.setLeftChild(src); // 插入
return true;
} else { // 说明有左节点
Node parent = parentNode.getLeftChild(); // 子节点为父节点
insert(src, parent); // 递归
}
} else { // 大于等于 往右边插
if (parentNode.getRightChild() == null) { // 如果等于空
parentNode.setRightChild(src); // 插入
return true;
} else { // 说明有左节点
Node parent = parentNode.getRightChild(); // 子节点为父节点
insert(src, parent); // 递归
}
}
return false;
}
/**
* 实现二叉树的先序遍历 根 左 右
*
* @return
*/
public ArrayList<Integer> nlr() {
result.clear(); // 使用前先清除存放结果的容器
ArrayList<Node> nodes = new ArrayList<Node>();
nodes = NLR(root);
// 取出节点 剥皮取出数据存放到容器内
ArrayList<Integer> arr = new ArrayList<Integer>();
for (Node node : nodes) {
arr.add(node.getNum());
}
return arr;
}
/**
* 先序遍历的实现方法 根 左 右
*
* @param nodes
* @return
*/
private ArrayList<Node> NLR(Node root) {
if (root.getLeftChild() != null) { // 如果有左节点
Node parent = root.getLeftChild(); // 左当根
result.add(root); // 先把自己(根)添加进去,再左右
NLR(parent);
}
if (root.getRightChild() != null) { // 如果有右节点
Node parent = root.getRightChild(); // 右当根
if (root.getLeftChild() == null) // 因为有左节点的 都已经把自己添加过了,所以把没有左节点的在添加进去
result.add(root); // 先把自己(根)添加进去,再左右
NLR(parent);
}
if (root.getLeftChild() == null && root.getRightChild() == null) {
result.add(root); // 如果没有子节点,把自己添加进去
}
return result;
}
/**
* 二叉树的中序遍历
*
* @return
*/
public ArrayList<Integer> lnr() {
result.clear(); // 清空容器
// 扒皮
ArrayList<Integer> arr = new ArrayList<Integer>();
for (Node node : LNR(root)) {
arr.add(node.getNum());
}
return arr;
}
/**
* 实现二叉树的中序遍历 不管怎么样 都是先 左 根 右 有重复值
*/
private ArrayList<Node> LNR(Node root) {
if (root.getLeftChild() != null) { // 如果左边有
Node parent = root.getLeftChild(); // 左子节点当父节点往下找
LNR(parent);
result.add(root); // 当儿子们都找完后自己在加进去
}
// 如果左右都有
if (root.getLeftChild() != null && (root.getRightChild() != null)) {
result.remove(root); // 先把自己删了,防止放右前 的放中导致重复
}
if (root.getRightChild() != null) { // 如果右边有
Node parent = root.getRightChild(); // 右边有,右节点当父节点,但是还是得先判断左子树
result.add(root); // 按照顺序 左中右 先把自己(中)添加里面
LNR(parent); // 判断
}
if (root.getLeftChild() == null && (root.getRightChild() == null)) {
result.add(root); // 如果左右都没有就把自己加里面
}
return result;
}
/**
* 二叉树的后序遍历 左右根
*
* @return
*/
public ArrayList<Integer> lrn() {
result.clear();
ArrayList<Integer> arr = new ArrayList<Integer>();
for (Node node : LRN(root)) {
arr.add(node.getNum());
}
return arr;
}
/**
* 实现后序遍历 左右根
*/
private ArrayList<Node> LRN(Node root) {
if (root.getLeftChild() != null) { // 如果有左
Node parent = root.getLeftChild(); // 左当父
LRN(parent); // 递归
result.add(root); // 回来在把自己填进去
}
if (root.getLeftChild() != null && root.getRightChild() != null) { // 如果两边都有
result.remove(root); // 先把自己删了
}
if (root.getRightChild() != null) { // 如果有右
Node parent = root.getRightChild(); // 右当父
LRN(parent);
result.add(root); // 右边把自己填进去
}
if (root.getLeftChild() == null && root.getRightChild() == null) {// 如果都没有
result.add(root); // 自己填进去
}
return result;
}
/**
* 返回二叉树的层数
* 最大数即为深度
*/
public int getFloor() {
ArrayList<Integer> maxs = treeDeep(root);
int max =maxs.get(0);
for (int i = 0; i < maxs.size()-1; i++) {
if(maxs.get(i) < maxs.get(i+1)) {
max = maxs.get(i+1);
}
}
return max;
}
/**
* 遍历所有分支 存放到floors容器中
* @return
*/
private ArrayList<Integer> treeDeep(Node node) {
//如果是双叶子节点
if(node.getLeftChild() != null && node.getRightChild() != null) {
floor++;
temp = floor;
treeDeep(node.getLeftChild());
treeDeep(node.getRightChild());
}
//如果只有左
if(node.getLeftChild()!=null && node.getRightChild()==null) {
floor++;
treeDeep(node.getLeftChild());
}
//如果只有右
if(node.getLeftChild()==null && node.getRightChild()!=null) {
floor++;
treeDeep(node.getRightChild());
}
//如果都没有
if(node.getLeftChild()==null &&node.getRightChild()==null) {
floors.add(floor);
floor = temp;
temp = -1;
}
return floors;
}
}
class Node {
private int num;
private Node leftChild;
private Node rightChild;
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public Node getLeftChild() {
return leftChild;
}
public void setLeftChild(Node leftChild) {
this.leftChild = leftChild;
}
public Node getRightChild() {
return rightChild;
}
public void setRightChild(Node rightChild) {
this.rightChild = rightChild;
}
}
public class BinaryTree {
public static void main(String[] args) {
Tree t1 = new Tree();
t1.add(50);
t1.add(20);
t1.add(70);
t1.add(15);
t1.add(60);
t1.add(80);
t1.add(62);
System.out.println("先序遍历---"+t1.nlr().toString()); // 先序遍历
System.out.println("中序遍历---"+t1.lnr().toString()); // 中序遍历
System.out.println("后序遍历---"+t1.lrn().toString()); // 后序遍历
System.out.println("深度---"+t1.getFloor());
}
}
结果:
先序遍历—[50, 20, 15, 70, 60, 62, 80]
中序遍历—[15, 20, 50, 60, 62, 70, 80]
后序遍历—[15, 20, 62, 60, 80, 70, 50]
深度—4