二叉樹之統計二叉樹的節點個數
一,問題描述
給定一顆二叉樹,已知其根結點。
①計算二叉樹所有結點的個數
②計算二叉樹中葉子結點的個數
③計算二叉樹中滿節點(度為2)的個數
二,算法分析
找出各個問題的基准條件,然后采用遞歸的方式實現。
①計算二叉樹所有結點的個數
1)當樹為空時,結點個數為0,否則為根節點個數 加上 根的左子樹中節點個數 再加上 根的右子樹中節點的個數
借助遍歷二叉樹的思路,每訪問一個結點,計數增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 }

