概述
遍历二叉树在上一篇文章中已经讲过了,那如何求一颗二叉树的高度呢?这一讲就讲这个问题。
思路
其实这个思路很难说清楚,大致的意思就是每遍历一层就把高度加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); } }