二叉樹最大深度(高度)/結點個數 / 葉子結點個數 / 第k層結點個數的求解
阿新 • • 發佈:2021-02-08
技術標籤: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
該例項的二叉樹圖如下所示: