二叉樹的數組表示:
一、數據結構的本質
二叉樹在很多應用的地方,其實很多時候並不需要去建樹。大多數學生陷入一個誤區,二叉樹一定要形如下面的樣子。
package tree; public class BinaryTree <T>{ private Node root; class Node{ T data; Node left; Node right; Node(T data){ this.data=data; this.left=null; this.right=null; } } public BinaryTree(){ root = new Node(null); } /** * 各種遍歷 */ }
這其實在某種程度上陷入了一個誤區。認為只要是樹就長這樣。其實樹還可以這樣定義。
public class BinaryTree{ int[] tree; /** * @param num 結點數 */ public BinaryTree(int num) { tree = new int[num]; }; /** * 其他方法 */ public ...{ 。。。 } }
有些朋友可能會奇怪。為什么樹還可以這么定義呢?和書上教的並不一樣啊。
其實數據結構只是一種思維,一種思想,我們用多種方法來實現這種思想。
二、實際應用。
對於任何數據結構來說,沒有實際應用都是紙上談兵。
這時,我挑選了一道題。題目選自算法競賽入門經典。
樣例輸入: 4 2 3 4 10 1 2 2 8 128 16 12345 樣例輸出: 12 7 512 3 255 36358
分析這道題。如果對這個題目進行建樹,那我們需要寫出很多很多代碼,首先要定義數據結構,其次要根據數據結構定義對應的方法。
這無疑對我們來說是很頭疼的一件事。那么對於此次實現,我們應該定義 倆個規則:
一、二叉樹的倆個子節點與索引的關系
對於索引為K的節點,其左孩子為(2*K) 右孩子為( 2*K+1)
二、二叉樹的根節點位置
為了方便編程,我們設置根節點的索引為1 即root = Tree[1]
然后根據此題邏輯,我們稍加思考即可寫出以下代碼
package first; import java.util.Scanner; /** * @author GodofOrange * @算法競賽入門經典:P149 */ public class A { // 樹的數組 對於任何一個節點索引K // 索引K==0不參與此次算法 // 其左子節點和右子節點的編號為2K和2K+1 // Tree false=關閉 true=打開 public static boolean[] Tree = new boolean[2 << 20 - 1]; public static void main(String[] args) { Scanner sc = new Scanner(System.in); int D = sc.nextInt(); int I = sc.nextInt(); int K = 0; // 讓N個小球落下 for (int i = 0; i < I; i++) { K= 1; while(true) { //小球滑到該處 將true改成false; Tree[K] = !Tree[K]; //如果Tree[K]=true 往左滑,否則往右滑 K = Tree[K] ? K*2:K*2+1; if(K>(2<<D-1)-1)break; } } sc.close(); System.out.println(K/2); } }
這是運行后的結果。
三、總結
無論何種數據結構,都可以有很多種實現方法,不一定非得像書中定義的ADT那種格式,也不要將思想局限於此。