二叉樹之統計二叉樹的節點個數node
一,問題描述算法
給定一顆二叉樹,已知其根結點。dom
①計算二叉樹全部結點的個數ui
②計算二叉樹中葉子結點的個數this
③計算二叉樹中滿節點(度爲2)的個數spa
二,算法分析code
找出各個問題的基準條件,而後採用遞歸的方式實現。blog
①計算二叉樹全部結點的個數遞歸
1)當樹爲空時,結點個數爲0,不然爲根節點個數 加上 根的左子樹中節點個數 再加上 根的右子樹中節點的個數element
藉助遍歷二叉樹的思路,每訪問一個結點,計數增1。所以,可以使用相似於先序遍歷的思路來實現,代碼以下:
1 //計算樹中節點個數 2 private int nubmerOfNodes(BinaryNode<T> root){ 3 int nodes = 0; 4 if(root == null) 5 return 0; 6 else{ 7 nodes = 1 + nubmerOfNodes(root.left) + nubmerOfNodes(root.right); 8 } 9 return nodes; 10 }
計算樹中節點個數的代碼方法與計算樹的高度的代碼很是類似!
②計算葉子結點的個數
1)當樹爲空時,葉子結點個數爲0
2)當某個節點的左右子樹均爲空時,代表該結點爲葉子結點,返回1
3)當某個節點有左子樹,或者有右子樹時,或者既有左子樹又有右子樹時,說明該節點不是葉子結點,所以葉結點個數等於左子樹中葉子結點個數 加上 右子樹中葉子結點的個數
這種形式的遞歸返回的node值 是最外層方法的node。
1 //計算樹中葉結點的個數 2 private int numberOfLeafs(BinaryNode<T> root){ 3 int nodes = 0; 4 if(root == null) 5 return 0; 6 else if(root.left == null && root.right == null) 7 return 1; 8 else 9 nodes = numberOfLeafs(root.left) + numberOfLeafs(root.right); 10 return nodes; 11 }
③計算滿節點的個數(對於二叉樹而言,滿節點是度爲2的節點)
滿節點的基準狀況有點複雜:
1)當樹爲空時,滿節點個數爲0
2)當樹中只有一個節點時,滿節點個數爲0
3)當某節點只有左子樹時,須要進一步判斷左子樹中是否存在滿節點
4)當某節點只有右子樹時,須要進一步判斷右子樹中是否存在滿節點
5)當某節點即有左子樹,又有右子樹時,說明它是滿結點。可是因爲它的左子樹或者右子樹中可能還存在滿結點,所以滿結點個數等於該節點加上該節點的左子樹中滿結點的個數 再加上 右子樹中滿結點的個數。
代碼以下:
1 //計算樹中度爲2的節點的個數--滿節點的個數 2 private int numberOfFulls(BinaryNode<T> root){ 3 int nodes = 0; 4 if(root == null) 5 return 0; 6 else if(root.left == null && root.right == null) 7 return 0; 8 else if(root.left == null && root.right != null) 9 nodes = numberOfFulls(root.right); 10 else if(root.left != null && root.right == null) 11 nodes = numberOfFulls(root.left); 12 else 13 nodes = 1 + numberOfFulls(root.left) + numberOfFulls(root.right); 14 return nodes; 15 }
對於二叉樹而言,有一個公式:度爲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 }
二,完整程序代碼以下:
1 import c2.C2_2_8; 2 3 public class BinarySearchTree<T extends Comparable<? super T>> { 4 5 private static class BinaryNode<T> { 6 T element; 7 BinaryNode<T> left; 8 BinaryNode<T> right; 9 10 public BinaryNode(T element) { 11 this(element, null, null); 12 } 13 14 public BinaryNode(T element, BinaryNode<T> left, BinaryNode<T> right) { 15 this.element = element; 16 this.left = left; 17 this.right = right; 18 } 19 20 public String toString() { 21 return element.toString(); 22 } 23 } 24 25 private BinaryNode<T> root; 26 27 public BinarySearchTree() { 28 root = null; 29 } 30 31 public void insert(T ele) { 32 root = insert(ele, root);// 每次插入操做都會'更新'根節點. 33 } 34 35 private BinaryNode<T> insert(T ele, BinaryNode<T> root) { 36 if (root == null) 37 return new BinaryNode<T>(ele); 38 int compareResult = ele.compareTo(root.element); 39 if (compareResult > 0) 40 root.right = insert(ele, root.right); 41 else if (compareResult < 0) 42 root.left = insert(ele, root.left); 43 else 44 ; 45 return root; 46 } 47 48 public int height() { 49 return height(root); 50 } 51 52 private int height(BinaryNode<T> root) { 53 if (root == null) 54 return -1;// 葉子節點的高度爲0,空樹的高度爲1 55 56 return 1 + (int) Math.max(height(root.left), height(root.right)); 57 } 58 59 public int numberOfNodes(BinarySearchTree<T> tree){ 60 return nubmerOfNodes(tree.root); 61 } 62 63 //計算樹中節點個數 64 private int nubmerOfNodes(BinaryNode<T> root){ 65 int nodes = 0; 66 if(root == null) 67 return 0; 68 else{ 69 nodes = 1 + nubmerOfNodes(root.left) + nubmerOfNodes(root.right); 70 } 71 return nodes; 72 } 73 74 75 public int numberOfLeafs(BinarySearchTree<T> tree){ 76 return numberOfLeafs(tree.root); 77 } 78 //計算樹中葉結點的個數 79 private int numberOfLeafs(BinaryNode<T> root){ 80 int nodes = 0; 81 if(root == null) 82 return 0; 83 else if(root.left == null && root.right == null) 84 return 1; 85 else 86 nodes = numberOfLeafs(root.left) + numberOfLeafs(root.right); 87 return nodes; 88 } 89 90 public int numberOfFulls(BinarySearchTree<T> tree){ 91 return numberOfFulls(tree.root); 92 // return numberOfLeafs(tree.root) > 0 ? numberOfLeafs(tree.root)-1 : 0;// n(2)=n(0)-1 93 } 94 //計算樹中度爲2的節點的個數--滿節點的個數 95 private int numberOfFulls(BinaryNode<T> root){ 96 int nodes = 0; 97 if(root == null) 98 return 0; 99 else if(root.left == null && root.right == null) 100 return 0; 101 else if(root.left == null && root.right != null) 102 nodes = numberOfFulls(root.right); 103 else if(root.left != null && root.right == null) 104 nodes = numberOfFulls(root.left); 105 else 106 nodes = 1 + numberOfFulls(root.left) + numberOfFulls(root.right); 107 return nodes; 108 } 109 110 111 public static void main(String[] args) { 112 BinarySearchTree<Integer> intTree = new BinarySearchTree<>(); 113 double averHeight = intTree.averageHeigth(1, 6, intTree); 114 System.out.println("averageheight = " + averHeight); 115 116 /*-----------All Nodes-----------------*/ 117 int totalNodes = intTree.numberOfNodes(intTree); 118 System.out.println("total nodes: " + totalNodes); 119 120 /*-----------Leaf Nodes-----------------*/ 121 int leafNodes = intTree.numberOfLeafs(intTree); 122 System.out.println("leaf nodes: " + leafNodes); 123 124 /*-----------Full Nodes-----------------*/ 125 int fullNodes = intTree.numberOfFulls(intTree); 126 System.out.println("full nodes: " + fullNodes); 127 } 128 129 public double averageHeigth(int tree_numbers, int node_numbers, BinarySearchTree<Integer> tree) { 130 int tree_height, totalHeight = 0; 131 for(int i = 1; i <= tree_numbers; i++){ 132 int[] randomNumbers = C2_2_8.algorithm3(node_numbers); 133 //build tree 134 for(int j = 0; j < node_numbers; j++) 135 { 136 tree.insert(randomNumbers[j]); 137 System.out.print(randomNumbers[j] + " "); 138 } 139 System.out.println(); 140 tree_height = tree.height(); 141 System.out.println("height:" + tree_height); 142 143 totalHeight += tree_height; 144 // tree.root = null;//for building next tree 145 } 146 return (double)totalHeight / tree_numbers; 147 } 148 }