求二叉樹中第K層結點的個數


一,問題描述

構建一棵二叉樹(不一定是二叉查找樹),求出該二叉樹中第K層中的結點個數(根結點為第0層)

 

二,二叉樹的構建

定義一個BinaryTree類來表示二叉樹,二叉樹BinaryTree 又是由各個結點組成的,因此需要定義一個結點類BinaryNode,BinaryNode作為BinaryTree的內部類。

此外,在BinaryTree中需要一定一個BinaryNode屬性來表示樹的根結點。

 1 public class BinaryTree<T extends Comparable<? super T>> {
 2     
 3     private static class BinaryNode<T>{
 4         T element;
 5         BinaryNode<T> left;
 6         BinaryNode<T> right;
 7         
 8         public BinaryNode(T element) {
 9             this.element = element;
10             left = right = null;
11         }
12     
13         public BinaryNode(T element, BinaryNode<T> left, BinaryNode<T> right){
14             this.element = element;
15             this.left = left;
16             this.right = right;
17         }
18     }
19     
20     private BinaryNode<T> root;
21 
22 //other code.....

第一行是二叉樹類的定義,第三行是結點類的定義,第20行是二叉樹根的定義。

 

三,求解第K層結點個數的算法實現

感覺對二叉樹中的許多操作都可以用遞歸來實現。因此,二叉樹是理解遞歸一個好實例。比如,二叉樹的操作之統計二叉樹中節點的個數二叉樹的先序遍歷和后序遍歷的應用--輸出文件和統計目錄大小

求第K層結點的個數也可以用遞歸來實現:

①若二叉樹為空或者K小於0,返回0

②若K等於0,第0層就是樹根,根只有一個,返回1

③若K大於0,返回左子樹中第K-1層結點個數 加上 右子樹中第K-1層結點的個數

因為,第K層結點,相對於根的左子樹 和 右子樹 而言,就是第K-1層結點

 

其實,這是有改進的地方:對於K<0的情形,准確地說:它只是一個非法輸入,而不是遞歸的結束條件(基准條件)。可以看出,①不要把非法輸入與遞歸的基准條件混淆,②把非法輸入的判斷放到遞歸中判斷的開銷是很大的。因為每進行一次遞歸就需要進行一次非法輸入判斷。而如果在開始就把非法輸入過濾掉,在遞歸過程中就不會存在每一次遞歸就判斷一次非法輸入了。

遞歸的基准條件只有兩個:

1) k==0 當遞歸到K==0時,說明:第K層是有結點的

2) root==null  當遞歸到root==null時,說明:第K層沒有結點

因此,可以進一步將代碼改進如下:這樣,不需要在每次遞歸的過程中還可能附加一次 k<0 的判斷

 1     /**
 2      * 
 3      * @param k
 4      * @return 二叉樹中第K層結點的個數(根位於第0層)
 5      */
 6     public int k_nodes(int k){
 7         if(k < 0)
 8             return 0;
 9         return k_nodes(root, k);
10     }
11     private int k_nodes(BinaryNode<T> root, int k){
12         if(root == null)
13             return 0;
14         if(k == 0)
15             return 1;//根結點
16         else
17             return k_nodes(root.left, k-1) + k_nodes(root.right, k-1);
18     }

 

可參考:按層打印二叉樹--每行打印一層 來測試每一層是否有正確的結點個數。

四,代碼實現

 1 public class BinaryTree<T extends Comparable<? super T>> {
 2     
 3     private static class BinaryNode<T>{
 4         T element;
 5         BinaryNode<T> left;
 6         BinaryNode<T> right;
 7         
 8         public BinaryNode(T element) {
 9             this.element = element;
10             left = right = null;
11         }
12     }
13     
14     private BinaryNode<T> root;
15     
16     /**
17      * 向二叉樹中插入一個元素
18      * @param element
19      */
20     public void insert(T element){
21         root = insert(root, element);
22     }
23     private BinaryNode<T> insert(BinaryNode<T> root, T element){
24         if(root == null)
25             return new BinaryNode<T>(element);
26         int r = (int)(2*Math.random());
27         //隨機地將元素插入到左子樹 或者 右子樹中
28         if(r==0)
29             root.left = insert(root.left, element);
30         else
31             root.right = insert(root.right, element);
32         return root;
33     }
34     
35     /**
36      * 
37      * @param k
38      * @return 二叉樹中第K層結點的個數(根位於第0層)
39      */
40     public int k_nodes(int k){
41         return k_nodes(root, k);
42     }
43     private int k_nodes(BinaryNode<T> root, int k){
44         if(root == null || k < 0)
45             return 0;
46         if(k == 0)
47             return 1;//根結點
48         else
49             return k_nodes(root.left, k-1) + k_nodes(root.right, k-1);
50     }
51     
52     public static void main(String[] args) {
53         BinaryTree<Integer> tree = new BinaryTree<>();
54         
55         int[] ele = C2_2_8.algorithm1(4);//構造一個隨機數組,數組元素的范圍為[1,4]
56         for (int i = 0; i < ele.length; i++) {
57             tree.insert(ele[i]);
58         }
59         
60         int k_nodes = tree.k_nodes(2);//第二層
61         int k_nodes2 = tree.k_nodes(-1);//第-1層
62         int k_nodes3 = tree.k_nodes(0);
63         int k_nodes4 = tree.k_nodes(1);
64         int k_nodes5 = tree.k_nodes(4);//若超過了樹的高度,結果為0
65         System.out.println(k_nodes);
66         System.out.println(k_nodes2);
67         System.out.println(k_nodes3);
68         System.out.println(k_nodes4);
69         System.out.println(k_nodes5);
70     }
71 }

 

關於 C2_2_8類,參考:隨機序列生成算法---生成前N個整數的一組隨機序列

 

五,參考資料

http://blog.csdn.net/luckyxiaoqiang/article/details/7518888


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM