1. 程式人生 > 其它 >二叉樹最大深度(高度)/結點個數 / 葉子結點個數 / 第k層結點個數的求解

二叉樹最大深度(高度)/結點個數 / 葉子結點個數 / 第k層結點個數的求解

技術標籤:Java資料結構Java資料結構二叉樹DFS/BFSjava

一、二叉樹最大深度(高度)

//求二叉樹最大深度/高度(DFS)
	public int maxDepth1(Node root) {
		if(root==null) {//空樹高度為0
			return 0;
		}
		int leftDepth=maxDepth1(root.left);//遞迴計算左子樹高度
		int rightDepth=maxDepth1(root.right);//遞迴計算右子樹高度
		return Math.max(leftDepth, rightDepth)+1;//取出左右子樹最大值再加上根結點高度為1
} //求二叉樹最大深度/高度(BFS) public int maxDepth2(Node root) { if(root==null) {//空樹高度為0 return 0; } Queue<Node> queue=new LinkedList<>(); queue.offer(root);//將根結點入佇列 int res=0;//儲存二叉樹的高度 while(!queue.isEmpty()) {//遍歷每層 int size=queue.size();//當前層的結點數量 while(size>0) { Node temp=queue.
poll(); if(temp.left!=null) {//當前結點左節點存在入佇列 queue.offer(temp.left); } if(temp.right!=null) {//當前結點右節點存在入佇列 queue.offer(temp.right); } size--; } res++;//每遍歷完一層,將層數加一 } return res; }

二、二叉樹結點個數

//求二叉樹的結點數(方法一)
	public int nodeCount1(Node root) {
		if(root==null) {
			return
0; } return nodeCount1(root.left)+nodeCount1(root.right)+1; } //求二叉樹的結點數(方法二) public static int count2 = 0;// 記錄結點個數 public int nodeCount2(Node root) { //int res = 0;// 記錄結點個數 if (root == null) { return 0; } count2++;//在遍歷時所有的結點都會訪問到,每訪問一個結點就將count2加一 nodeCount2(root.left); nodeCount2(root.right); return count2; } // 求二叉樹的結點數(方法三) public int nodeCount3(Node root) { int res = 0;// 記錄結點的個數 if (root == null) {// 空樹直接返回0 return 0; } Stack<Node> stack = new Stack<>(); stack.push(root); while (!stack.isEmpty()) { Node temp = stack.pop(); res++;// 在遍歷時所有的結點都會訪問到,每訪問一個結點就將res加一 if (temp.left != null) { stack.push(temp.left); } if (temp.right != null) { stack.push(temp.right); } } return res; }

三、二叉樹葉子結點個數

//求二叉樹的葉子數(方法一)
	public int leafCount1(Node root){
		if(root==null) {//空樹直接返回0
			return 0;
		}
		if(root.left==null&&root.right==null) {//沒有左右子樹即為葉子結點
			return 1;
		}
		return leafCount1(root.left)+leafCount1(root.right);
	}
	
//求二叉樹的葉子數(方法二)
	public static int count1 = 0;// 記錄葉子結點的個數(該count1定義必須放在函式體外,否則每次遍歷時重新進行函式體時有=又重新將count1置為零,下面的count2同理)
	public int leafCount2(Node root) {
		// int res=0;//記錄葉子結點的個數
		if (root == null) {// 空樹直接返回0
			return 0;
		}
		if (root.left == null && root.right == null) {// 沒有左右子樹即為葉子結點將count1加一
			count1++;
		} else {// 否則的話就繼續遍歷,繼續找左右孩子均為空的結點
			leafCount2(root.left);
			leafCount2(root.right);
		}
		return count1;
	}
	
//求二叉樹的葉子數(方法三)
	public int leafCount3(Node root) {
		int res=0;//記錄葉子結點的個數
		if (root == null) {//空樹直接返回0
			return 0;
		}
		Stack<Node> stack=new Stack<>();
		stack.push(root);
		while(!stack.isEmpty()) {
			Node temp=stack.pop();
			if (temp.left == null && temp.right == null) {//沒有左右子樹即為葉子結點將res加一
				res++;
			}
			if(temp.left!=null) {
				stack.push(temp.left);
			}
			if(temp.right!=null) {
				stack.push(temp.right);
			}
		}
		return res;
	}

四、二叉樹第k層結點個數

//求第k層結點個數
	public int kLevelCount(Node root,int k) {
		if(root==null) {//空樹直接返回0
			return 0;
		}
		if(k==1) {//k==1即求根節點的個數,直接返回1
			return 1;
		}
		return kLevelCount(root.left,k-1)+kLevelCount(root.right,k-1);//k層節點的個數=根節點左子樹的k-1層節點個數+根節點右子樹的k-1層節點個數
		
	}

五、完整程式碼實現

package fighting;

import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

public class BinaryTree {
	
	public Node BuildTree() {//構造二叉樹
		Node A=new Node('A');
		Node B=new Node('B');
        Node C=new Node('C');
        Node D=new Node('D');
        Node E=new Node('E');
        Node F=new Node('F');
        Node G=new Node('G');
        Node H=new Node('H');
        A.left=B;
        A.right=C;
        B.left=D;
        B.right=E;
        C.left=F;
        C.right=G;
        E.right=H;
        return A;
	}
	
	//求二叉樹最大深度/高度(DFS)
	public int maxDepth1(Node root) {
		if(root==null) {//空樹高度為0
			return 0;
		}
		int leftDepth=maxDepth1(root.left);//遞迴計算左子樹高度
		int rightDepth=maxDepth1(root.right);//遞迴計算右子樹高度
		return Math.max(leftDepth, rightDepth)+1;//取出左右子樹最大值再加上根結點高度為1
	}

	//求二叉樹最大深度/高度(BFS)
	public int maxDepth2(Node root) {
		if(root==null) {//空樹高度為0
			return 0;
		}
		Queue<Node> queue=new LinkedList<>();
		queue.offer(root);//將根結點入佇列
		int res=0;//儲存二叉樹的高度
		while(!queue.isEmpty()) {//遍歷每層
			int size=queue.size();//當前層的結點數量
			while(size>0) {
				Node temp=queue.poll();
				if(temp.left!=null) {//當前結點左節點存在入佇列
					queue.offer(temp.left);
				}
				if(temp.right!=null) {//當前結點右節點存在入佇列
					queue.offer(temp.right);
				}
				size--;
			}
			res++;//每遍歷完一層,將層數加一
		}
		return res;
	}
	
	//求二叉樹的葉子數(方法一)
	public int leafCount1(Node root){
		if(root==null) {//空樹直接返回0
			return 0;
		}
		if(root.left==null&&root.right==null) {//沒有左右子樹即為葉子結點
			return 1;
		}
		return leafCount1(root.left)+leafCount1(root.right);
	}
	
	//求二叉樹的葉子數(方法二)
	public static int count1 = 0;// 記錄葉子結點的個數(該count1定義必須放在函式體外,否則每次遍歷時重新進行函式體時有=又重新將count1置為零,下面的count2同理)
	public int leafCount2(Node root) {
		// int res=0;//記錄葉子結點的個數
		if (root == null) {// 空樹直接返回0
			return 0;
		}
		if (root.left == null && root.right == null) {// 沒有左右子樹即為葉子結點將count1加一
			count1++;
		} else {// 否則的話就繼續遍歷,繼續找左右孩子均為空的結點
			leafCount2(root.left);
			leafCount2(root.right);
		}
		return count1;
	}
	
	//求二叉樹的葉子數(方法三)
	public int leafCount3(Node root) {
		int res=0;//記錄葉子結點的個數
		if (root == null) {//空樹直接返回0
			return 0;
		}
		Stack<Node> stack=new Stack<>();
		stack.push(root);
		while(!stack.isEmpty()) {
			Node temp=stack.pop();
			if (temp.left == null && temp.right == null) {//沒有左右子樹即為葉子結點將res加一
				res++;
			}
			if(temp.left!=null) {
				stack.push(temp.left);
			}
			if(temp.right!=null) {
				stack.push(temp.right);
			}
		}
		return res;
	}
	
	
	//求二叉樹的結點數(方法一)
	public int nodeCount1(Node root) {
		if(root==null) {
			return 0;
		}
		return nodeCount1(root.left)+nodeCount1(root.right)+1;
	}
	
	//求二叉樹的結點數(方法二)
	public static int count2 = 0;// 記錄結點個數
	public int nodeCount2(Node root) {
		//int res = 0;// 記錄結點個數
		if (root == null) {
			return 0;
		}
		count2++;//在遍歷時所有的結點都會訪問到,每訪問一個結點就將count2加一
		nodeCount2(root.left);
		nodeCount2(root.right);
		return count2;
	}
	
	// 求二叉樹的結點數(方法三)
	public int nodeCount3(Node root) {
		int res = 0;// 記錄結點的個數
		if (root == null) {// 空樹直接返回0
			return 0;
		}
		Stack<Node> stack = new Stack<>();
		stack.push(root);
		while (!stack.isEmpty()) {
			Node temp = stack.pop();
			res++;// 在遍歷時所有的結點都會訪問到,每訪問一個結點就將res加一
			if (temp.left != null) {
				stack.push(temp.left);
			}
			if (temp.right != null) {
				stack.push(temp.right);
			}
		}
		return res;
	}

	//求第k層結點個數
	public int kLevelCount(Node root,int k) {
		if(root==null) {//空樹直接返回0
			return 0;
		}
		if(k==1) {//k==1即求根節點的個數,直接返回1
			return 1;
		}
		return kLevelCount(root.left,k-1)+kLevelCount(root.right,k-1);//k層節點的個數=根節點左子樹的k-1層節點個數+根節點右子樹的k-1層節點個數
		
	}
	public static void main(String[] args) {
		BinaryTree binaryTree=new BinaryTree();
		Node root=binaryTree.BuildTree();
		System.out.println("二叉樹的最大高度為(DFS):"+binaryTree.maxDepth1(root));//DFS求二叉樹高度
		System.out.println("二叉樹的最大高度為(BFS):"+binaryTree.maxDepth2(root));//BFS求二叉樹高度
		System.out.println("二叉樹結點的個數為(方法一):"+binaryTree.nodeCount1(root));
		System.out.println("二叉樹結點的個數為(方法二):"+binaryTree.nodeCount2(root));
		System.out.println("二叉樹結點的個數為(方法三):"+binaryTree.nodeCount3(root));
		System.out.println("二叉樹葉子結點的個數為(方法一):"+binaryTree.leafCount1(root));
		System.out.println("二叉樹葉子結點的個數為(方法二):"+binaryTree.leafCount2(root));
		System.out.println("二叉樹葉子結點的個數為(方法三):"+binaryTree.leafCount3(root));
		System.out.printf("二叉樹第%d層結點個數數為:%d",3,binaryTree.kLevelCount(root,3));
	}
}

class Node{
	char val;
	Node left;
	Node right;
	public Node(char val) {//Node的建構函式
		this.val=val;
	}
}

執行結果:

二叉樹的最大高度為(DFS):4
二叉樹的最大高度為(BFS):4
二叉樹結點的個數為(方法一)8
二叉樹結點的個數為(方法二)8
二叉樹結點的個數為(方法三)8
二叉樹葉子結點的個數為(方法一)4
二叉樹葉子結點的個數為(方法二)4
二叉樹葉子結點的個數為(方法三)4
二叉樹第3層結點個數數為:4

該例項的二叉樹圖如下所示:
在這裡插入圖片描述