概述
遍历二叉树在上一篇文章中已经讲过了,那如何求一颗二叉树的高度呢?这一讲就讲这个问题。
思路
其实这个思路很难说清楚,大致的意思就是每遍历一层就把高度加1,那问题来了,怎么判断我这一层遍历结束了呢?这个可以通过记录每一层的个数,然后当把这一层的每一个都遍历之后就说明这一层遍历完了,那问题又来了,怎么记录每一层的个数呢?这个就有技巧了,思路是这样的,使用两个遍历同时进行,第一个遍历遍历下一层的时候,第二个遍历遍历上一层,当上一层遍历完的时候,下一层也就遍历完了,然后在这个过程中就可以通过一些标志位来让高度加1.
可能看了上面的思路更加迷糊了,下面直接看代码吧。
基础代码,就是二叉树的构成和每个节点的代码。
二叉树:
package com.example.demo.tree;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import org.omg.PortableInterceptor.INACTIVE;
import java.util.Comparator;
/**
* @author steve
* @date 2020/4/16 10:03 上午
*/
public class BinaryTree<E> {
private int size;
public Node<E> root;
private Comparator<E> comparator;
public BinaryTree(Comparator<E> comparator){
this.comparator = comparator;
}
public BinaryTree(){
this(null);
}
public void add(E element){
if (root == null){
Node node = new Node(element);
root = node;
}else {
Node<E> parent = root;
Node<E> node = root;
int com = 0;
while (node != null){
parent = node;
if (comparator == null){
com = ((Comparable)node.element).compareTo(element);
}else {
System.out.println("-------------");
com = comparator.compare(node.element,element);
}
if (com > 0){
node = node.left;
}else if (com < 0){
node = node.right;
}else {
node.element = element;
return;
}
}
Node<E> newNode = new Node(element);
if (com > 0){
parent.left = newNode;
newNode.parent = parent.left;
}else{
parent.right = newNode;
newNode.parent = parent.right;
}
}
size ++;
}
public boolean isEmpty(){
return size == 0;
}
public int size(){
return size;
}
public String toString() {
String d = root == null ? null : root.element + "";
if (root == null){
return "root:"+d;
}else {
String b = root.left == null ? null : root.left.element + "";
String c = root.right == null ? null : root.right.element + "";
return "root:"+d + ", left:" + b + ", right:"+ c;
}
}
public static void main(String[] args) {
//这种方式就是匿名内部类,通过给一个类传一个接口作为参数,然后这个通过一个匿名内部类是实现这个接口来传入实现。
BinaryTree<Integer> binaryTree = new BinaryTree<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;
}
});
BinaryTree<Integer> binaryTree1 = new BinaryTree<>();
binaryTree1.add(1);
binaryTree1.add(2);
binaryTree1.add(0);
System.out.println(binaryTree1.size());
System.out.println(binaryTree.toString());
}
}
节点:
package com.example.demo.tree;
/**
* @author steve
* @date 2020/4/18 3:16 下午
*/
public class Node<E> {
public Node<E> left;
public Node<E> right;
public Node<E> parent;
public E element;
public Node(E element){
this.element = element;
}
}
判断二叉树的高度
package com.example.demo.tree;
import java.util.ArrayList;
import java.util.List;
/**
* @author steve
* @date 2020/4/20 6:36 下午
* @description 求出二叉树的高度,通过递归和迭代的方式实现
*/
public class BinaryTreeHeight {
/**
* 通过递归的方式求出二叉树高度,这种方式很难想
* @param node
*/
public static int getHeightByRecursion(Node<Integer> node){
if (node == null || node == null) return 0;
int left = getHeightByRecursion(node.left);
int right = getHeightByRecursion(node.right);
if (left > right){
return left + 1;
}else {
return right + 1;
}
}
/**
* 通过迭代求出二叉树的高度
* @param node
*/
public static void getHeightByIteration(Node<Integer> node){
//这个就是慢迭代的下标
int front = -1;
//这个是记录每一层结尾处的下标
int last = 0;
//树的高度
int height = 0;
//这个是快迭代的下标
int rear = -1;
List<Node<Integer>> linkList = new ArrayList<>();
linkList.add(++rear,node);
Node<Integer> node1 = null;
while(front < rear){
node1 = linkList.get(++front);
if (node1.left != null){
linkList.add(++rear, node1.left);
}
if (node1.right != null){
linkList.add(++rear, node1.right);
}
if (front == last){
height++;
last = rear;
}
}
System.out.println(height);
}
public static void main(String[] args) {
BinaryTree<Integer> binaryTree = new BinaryTree();
binaryTree.add(7);
binaryTree.add(4);
binaryTree.add(10);
binaryTree.add(9);
binaryTree.add(11);
binaryTree.add(5);
binaryTree.add(3);
binaryTree.add(1);
binaryTree.add(0);
int height = getHeightByRecursion(binaryTree.root);
System.out.println(height);
getHeightByIteration(binaryTree.root);
}
}