剑指offer上一道比较基础的题目,但这个解法不仅可以求二叉树的深度同时可以求二叉树的最大层数,某一层的某一个节点 是一种比较通用的方法!
先建立数据模型
package Binary_tree;
public class Node {//二叉树节点
private int data;
private Node leftNode;
private Node rightNode;
public Node(int data, Node leftNode, Node rightNode){
this.data = data;
this.leftNode = leftNode;
this.rightNode = rightNode;
}
public int getData(){
return data;
}
public void setData(int data){
this.data = data;
}
public Node getLeftNode(){
return leftNode;
}
public void setLeftNode(Node leftNode){
this.leftNode = leftNode;
}
public Node getRightNode(){
return rightNode;
}
public void setRightNode(Node rightNode){
this.rightNode = rightNode;
}
}
递归解法比较简单:
private int getDeep(Node node){
if(node==null) return 0; //递归出口
int left = getDeep(node.getLeftNode()); //递归求左树深度
int right = getDeep(node.getRightNode()); //递归求右树深度
return Math.max(left, right)+1; //算上根节点返回左右树深度大值+1
}
非递归解法:
以该树为例:
A
/ \
B C
/ \ /
D E F
\ / \
G H J
-
经典的非递归层次遍历:利用辅助队列,先将头节点入队列,当队列不空时出队列的节点记为current,
当current左节点不空时入队列,其右节点不空时入队列,如此循环即可。
求深度:构造变量cur记录当前层访问到的节点数,width记录当前层的总个数,每当访问过一层层数deep++;
此种方法同时可以求最大宽度,访问第几层的第几个节点,是一种通用方法
package Binary_tree;
import java.util.LinkedList;
import static net.mindview.util.Print.*;
public class Deep {
public static Node init(){
Node J = new Node(8, null, null);
Node H = new Node(4, null, null);
Node G = new Node(2, null, null);
Node F = new Node(7, null, J);
Node E = new Node(5, H, null);
Node D = new Node(1, null, G);
Node C = new Node(9, F, null);
Node B = new Node(3, D, E);
Node A = new Node(6, B, C);
return A; //返回根节点
}
private void getDeep1(Node root,int d,int n){
Node result=null;
Node current; //记录当前节点
LinkedList<Node> queue = new LinkedList<Node>(); //声明辅助队列
int cur, width , deep=0 , maxwidth=0; //cur记录当前层所访问的个数,width为当前层的个数,deep记录层数
queue.offer(root);
while(!queue.isEmpty()){
cur=0;
width=queue.size(); //当前队列中所含元素的个数便是该层树的宽度
if(width>maxwidth) maxwidth=width; //若当前宽度大于最大宽度,则将当前宽度设为最大宽度
while(cur<width){
current=queue.poll();
if(deep+1==d&&cur+1==n) //找到符合条件的节点
result=current;
if(current.getLeftNode()!=null) //左节点存在则入队列
queue.offer(current.getLeftNode());
if(current.getRightNode()!=null) //右节点存在则入队列
queue.offer(current.getRightNode());
cur++;
}
deep++;
}
System.out.println("当前二叉树的深度为:"+deep+ " 其最大层数为:"+maxwidth);
System.out.println("该二叉树中第"+d+"层的第"+n+"个节点值为:"+result.getData());
}
private int getDeep(Node node){
if(node==null) return 0; //递归出口
int left = getDeep(node.getLeftNode()); //递归求左树深度
int right = getDeep(node.getRightNode()); //递归求右树深度
return Math.max(left, right)+1; //算上根节点返回左右树深度大值+1
}
public static void main(String[] args){
Deep obj = new Deep();
Node root = Deep.init();
obj.getDeep1(root, 3, 2); //寻找第三层的第二个节点,默认输入是有效的,本应该要做输入判断该点是否存在的
//在这里主要是介绍该算法的思想就没有去判断。
}
}
输出为:
当前二叉树的深度为:4 其最大层数为:3
该二叉树中第3层的第2个节点值为:5