作者:Grey
讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對這個(gè)行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價(jià)值的長期合作伙伴,公司提供的服務(wù)項(xiàng)目有:空間域名、虛擬主機(jī)、營銷軟件、網(wǎng)站建設(shè)、城關(guān)網(wǎng)站維護(hù)、網(wǎng)站推廣。原文地址:
博客園:判斷二叉樹是否為滿二叉樹
:判斷二叉樹是否為滿二叉樹
滿二叉樹定義方法1一個(gè)二叉樹,如果每一個(gè)層的結(jié)點(diǎn)數(shù)都達(dá)到大值,則這個(gè)二叉樹就是滿二叉樹。也就是說,如果一個(gè)二叉樹的層數(shù)為K,且結(jié)點(diǎn)總數(shù)是
(2^k) -1
,則它就是滿二叉樹。
使用公式,求二叉樹的層數(shù) k, 結(jié)點(diǎn)數(shù) n,如果滿足(2^k) -1 = n
,則為滿二叉樹。
定義數(shù)據(jù)結(jié)構(gòu)
public static class Info1 {public int height;
public int nodes;
public Info1(int h, int n) {height = h;
nodes = n;
}
}
其中height
表示二叉樹的層數(shù),nodes
表示二叉樹的結(jié)點(diǎn)個(gè)數(shù)。
定義遞歸函數(shù)
Info1 process1(Node head)
遞歸含義是:head 為頭的二叉樹的層數(shù)和點(diǎn)數(shù)都是多少,接下來就是 base case
即:head == null
的時(shí)候,此時(shí),height == 0
且nodes == 0
if (head == null) {return new Info1(0, 0);
}
接下來是普遍情況
// 去左樹上收集信息
Info1 leftInfo = process1(head.left);
// 去右樹上收集信息
Info1 rightInfo = process1(head.right);
// 整合成 head 自己的信息
int height = Math.max(leftInfo.height, rightInfo.height) + 1;
int nodes = leftInfo.nodes + rightInfo.nodes + 1;
return new Info1(height, nodes);
方法2定義如下數(shù)據(jù)結(jié)構(gòu)
public static class Info2 {public boolean isFull;
public int height;
public Info2(boolean f, int h) {isFull = f;
height = h;
}
}
其中isFull
表示是否為滿二叉樹,height
表示二叉樹的高度。
定義了這個(gè)數(shù)據(jù)結(jié)構(gòu)后,可以梳理可能性,如果以head
為頭的樹要符合滿二叉樹。則需要同時(shí)滿足下面三種情況
情況1:左樹是滿二叉樹
情況2:右樹是滿二叉樹;
情況3:左右樹的高度一樣。
定義遞歸函數(shù)
Info2 process2(Node head)
遞歸含義就是返回以head
為頭的二叉樹Info2
結(jié)構(gòu)信息。
base case是
if (h == null) {return new Info2(true, 0);
}
h == null
默認(rèn)是滿二叉樹,結(jié)點(diǎn)個(gè)數(shù)為0。
接下來是普遍情況,即去左右子樹收集相關(guān)信息,整合成以h
為頭二叉樹的信息。
// 去左子樹收集相關(guān)信息
Info2 leftInfo = process2(h.left);
// 去右子樹收集相關(guān)信息
Info2 rightInfo = process2(h.right);
// 整合成 h 自己的新
boolean isFull = leftInfo.isFull && rightInfo.isFull && leftInfo.height == rightInfo.height;
int height = Math.max(leftInfo.height, rightInfo.height) + 1;
return new Info2(isFull, height);
方法1 和 方法2 的時(shí)間復(fù)雜度都是O(n)
,即經(jīng)過一次后序遍歷的時(shí)間復(fù)雜度。
兩種解法的完整代碼(含測試代碼)如下
public class Code_IsFull {public static class Node {public int value;
public Node left;
public Node right;
public Node(int data) {this.value = data;
}
}
// 第一種方法
// 收集整棵樹的高度h,和節(jié)點(diǎn)數(shù)n
// 只有滿二叉樹滿足 : 2 ^ h - 1 == n
public static boolean isFull1(Node head) {if (head == null) {return true;
}
Info1 all = process1(head);
return (1<< all.height) - 1 == all.nodes;
}
public static class Info1 {public int height;
public int nodes;
public Info1(int h, int n) {height = h;
nodes = n;
}
}
public static Info1 process1(Node head) {if (head == null) {return new Info1(0, 0);
}
Info1 leftInfo = process1(head.left);
Info1 rightInfo = process1(head.right);
int height = Math.max(leftInfo.height, rightInfo.height) + 1;
int nodes = leftInfo.nodes + rightInfo.nodes + 1;
return new Info1(height, nodes);
}
// 第二種方法
// 收集子樹是否是滿二叉樹
// 收集子樹的高度
// 左樹滿 && 右樹滿 && 左右樹高度一樣 ->整棵樹是滿的
public static boolean isFull2(Node head) {if (head == null) {return true;
}
return process2(head).isFull;
}
public static class Info2 {public boolean isFull;
public int height;
public Info2(boolean f, int h) {isFull = f;
height = h;
}
}
public static Info2 process2(Node h) {if (h == null) {return new Info2(true, 0);
}
Info2 leftInfo = process2(h.left);
Info2 rightInfo = process2(h.right);
boolean isFull = leftInfo.isFull && rightInfo.isFull && leftInfo.height == rightInfo.height;
int height = Math.max(leftInfo.height, rightInfo.height) + 1;
return new Info2(isFull, height);
}
// for test
public static Node generateRandomBST(int maxLevel, int maxValue) {return generate(1, maxLevel, maxValue);
}
// for test
public static Node generate(int level, int maxLevel, int maxValue) {if (level >maxLevel || Math.random()< 0.5) {return null;
}
Node head = new Node((int) (Math.random() * maxValue));
head.left = generate(level + 1, maxLevel, maxValue);
head.right = generate(level + 1, maxLevel, maxValue);
return head;
}
public static void main(String[] args) {int maxLevel = 5;
int maxValue = 100;
int testTimes = 1000000;
System.out.println("測試開始");
for (int i = 0; i< testTimes; i++) {Node head = generateRandomBST(maxLevel, maxValue);
if (isFull1(head) != isFull2(head)) {System.out.println("出錯(cuò)了!");
}
}
System.out.println("測試結(jié)束");
}
}
更多算法和數(shù)據(jù)結(jié)構(gòu)筆記
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購,新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧