劍指offer之求二叉樹的深度(非遞歸的層次遍歷)Java實現

劍指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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章