一,問題描述
給定一顆二叉樹,已知其根結點。
①計算二叉樹所有結點的個數
②計算二叉樹中葉子結點的個數
③計算二叉樹中滿節點(度為2)的個數
二,算法分析
找出各個問題的基准條件,然后采用遞歸的方式實現。
①計算二叉樹所有結點的個數
1)當樹為空時,結點個數為0,否則為根節點個數 加上 根的左子樹中節點個數 再加上 根的右子樹中節點的個數
借助遍歷二叉樹的思路,每訪問一個結點,計數增1。因此,可使用類似於先序遍歷的思路來實現,代碼如下:
//計算樹中節點個數 private int nubmerOfNodes(BinaryNode<T> root){ int nodes = 0; if(root == null) return 0; else{ nodes = 1 + nubmerOfNodes(root.left) + nubmerOfNodes(root.right); } return nodes; }
計算樹中節點個數的代碼方法與計算樹的高度的代碼非常相似!
//求二叉樹的深度 public static int deep(Node node){ int h1, h2; if(node == null) {return 0; } else{ h1= deep(node.left); h2= deep(node.right); return (h1<h2)?h2+1:h1+1; } }
②計算葉子結點的個數
1)當樹為空時,葉子結點個數為0
2)當某個節點的左右子樹均為空時,表明該結點為葉子結點,返回1
3)當某個節點有左子樹,或者有右子樹時,或者既有左子樹又有右子樹時,說明該節點不是葉子結點,因此葉結點個數等於左子樹中葉子結點個數 加上 右子樹中葉子結點的個數
//計算樹中葉結點的個數 private int numberOfLeafs(BinaryNode<T> root){ int nodes = 0; if(root == null) return 0; else if(root.left == null && root.right == null) return 1; else nodes = numberOfLeafs(root.left) + numberOfLeafs(root.right); return nodes; }
③計算滿節點的個數(對於二叉樹而言,滿節點是度為2的節點)
滿節點的基准情況有點復雜:
1)當樹為空時,滿節點個數為0
2)當樹中只有一個節點時,滿節點個數為0
3)當某節點只有左子樹時,需要進一步判斷左子樹中是否存在滿節點
4)當某節點只有右子樹時,需要進一步判斷右子樹中是否存在滿節點
5)當某節點即有左子樹,又有右子樹時,說明它是滿結點。但是由於它的左子樹或者右子樹中可能還存在滿結點,因此滿結點個數等於該節點加上該節點的左子樹中滿結點的個數 再加上 右子樹中滿結點的個數。
//計算樹中度為2的節點的個數--滿節點的個數 private int numberOfFulls(BinaryNode<T> root){ int nodes = 0; if(root == null) return 0; else if(root.left == null && root.right == null) return 0; else if(root.left == null && root.right != null) nodes = numberOfFulls(root.right); else if(root.left != null && root.right == null) nodes = numberOfFulls(root.left); else nodes = 1 + numberOfFulls(root.left) + numberOfFulls(root.right); return nodes; }
對於二叉樹而言,有一個公式:度為2的結點個數等於度為0的結點個數減去1。 即:n(2)=n(0)-1
故可以這樣:
private int numberOfFulls(BinaryNode<T> root){ return numberOfLeafs(root) > 0 ? numberOfLeafs(root)-1 : 0;// n(2)=n(0)-1 }
三,完整程序代碼如下
public class BinarySearchTree<T extends Comparable<? super T>> { private static class BinaryNode<T> { T element; BinaryNode<T> left; BinaryNode<T> right; public BinaryNode(T element) { this(element, null, null); } public BinaryNode(T element, BinaryNode<T> left, BinaryNode<T> right) { this.element = element; this.left = left; this.right = right; } public String toString() { return element.toString(); } } private BinaryNode<T> root; public BinarySearchTree() { root = null; } public void insert(T ele) { root = insert(ele, root);// 每次插入操作都會'更新'根節點. } private BinaryNode<T> insert(T ele, BinaryNode<T> root) { if (root == null) return new BinaryNode<T>(ele); int compareResult = ele.compareTo(root.element); if (compareResult > 0) root.right = insert(ele, root.right); else if (compareResult < 0) root.left = insert(ele, root.left); else ; return root; } public int height() { return height(root); } private int height(BinaryNode<T> root) { if (root == null) return -1;// 葉子節點的高度為0,空樹的高度為1 return 1 + (int) Math.max(height(root.left), height(root.right)); } public int numberOfNodes(BinarySearchTree<T> tree){ return nubmerOfNodes(tree.root); } //計算樹中節點個數 private int nubmerOfNodes(BinaryNode<T> root){ int nodes = 0; if(root == null) return 0; else{ nodes = 1 + nubmerOfNodes(root.left) + nubmerOfNodes(root.right); } return nodes; } public int numberOfLeafs(BinarySearchTree<T> tree){ return numberOfLeafs(tree.root); } //計算樹中葉結點的個數 private int numberOfLeafs(BinaryNode<T> root){ int nodes = 0; if(root == null) return 0; else if(root.left == null && root.right == null) return 1; else nodes = numberOfLeafs(root.left) + numberOfLeafs(root.right); return nodes; } public int numberOfFulls(BinarySearchTree<T> tree){ return numberOfFulls(tree.root); // return numberOfLeafs(tree.root) > 0 ? numberOfLeafs(tree.root)-1 : 0;// n(2)=n(0)-1 } //計算樹中度為2的節點的個數--滿節點的個數 private int numberOfFulls(BinaryNode<T> root){ int nodes = 0; if(root == null) return 0; else if(root.left == null && root.right == null) return 0; else if(root.left == null && root.right != null) nodes = numberOfFulls(root.right); else if(root.left != null && root.right == null) nodes = numberOfFulls(root.left); else nodes = 1 + numberOfFulls(root.left) + numberOfFulls(root.right); return nodes; } public static void main(String[] args) { BinarySearchTree<Integer> intTree = new BinarySearchTree<>(); double averHeight = intTree.averageHeigth(1, 6, intTree); System.out.println("averageheight = " + averHeight); /*-----------All Nodes-----------------*/ int totalNodes = intTree.numberOfNodes(intTree); System.out.println("total nodes: " + totalNodes); /*-----------Leaf Nodes-----------------*/ int leafNodes = intTree.numberOfLeafs(intTree); System.out.println("leaf nodes: " + leafNodes); /*-----------Full Nodes-----------------*/ int fullNodes = intTree.numberOfFulls(intTree); System.out.println("full nodes: " + fullNodes); } public double averageHeigth(int tree_numbers, int node_numbers, BinarySearchTree<Integer> tree) { int tree_height, totalHeight = 0; for(int i = 1; i <= tree_numbers; i++){ int[] randomNumbers = C2_2_8.algorithm3(node_numbers); //build tree for(int j = 0; j < node_numbers; j++) { tree.insert(randomNumbers[j]); System.out.print(randomNumbers[j] + " "); } System.out.println(); tree_height = tree.height(); System.out.println("height:" + tree_height); totalHeight += tree_height; // tree.root = null;//for building next tree } return (double)totalHeight / tree_numbers; } }