android自定义绘制二叉树,安卓数据结构04-二叉树
數據結構04-二叉樹
一、樹的基本概念
1.樹
樹是n(n>=0)個節點的有限集。n=0時稱為空樹。在任意一顆非空樹中:
有且僅有一個特定的稱為根(Root)的節點;
當n>1時,其余節點可分為m(m>0)個互不相交的有限集T1、T2、......、Tm,其中每一個集合本事又是一顆樹,并且稱為根的子樹(SubTree)。
2.度
節點的度是節點擁有的子樹數。度為0的節點稱為葉子節點或終端節點,度不為0的節點稱為非終端節點或分支節點。除根節點以外,分支節點也稱為內部節點。樹的度是樹內各節點的度的最大值。
3.層次
節點的層次(Level)從根開始定義起,根為第一層,根的孩子為第二層。若某節點在第n層,則其字數的根就在第n+1層。其雙親在同一層的節點互為堂兄弟。樹中節點的最大層次稱為樹的深度(Depth)或高度。
4.森林
森林(Forest)是m(m>=0)棵互不相交的集合。
5.樹的存儲結構
簡單的順序存儲不能滿足樹的實現,一般結合順序存儲和鏈式存儲來實現,有四種表示方法:
雙親表示法:在每個節點中,附設一個指示器指示其雙親節點到鏈表中的位置。
孩子表示法:在每個節點中,附設幾個指示器指示子節點到鏈表中的位置。
雙親孩子表示法:在每個節點中,附設2個指示器,一個指示雙親節點,一個指示孩子鏈表(由它的孩子節點組成的單鏈表)。
孩子兄弟表示法:在每個節點中,附設2個指示器,一個指示它的第一個孩子節點,一個指向它的下一個兄弟節點。
二、二叉樹的基本概念
1.二叉樹
二叉樹(Binary Tree)是n(n>=0)個節點的有限集合,該集合或者位空集(稱為空二叉樹),或者有一個根節點和兩顆互不相交的、分別稱為根節點的左子樹和右子樹的二叉樹組成。
2.斜樹
斜樹是所有的節點都只有左子樹或右子樹的二叉樹,擁有左子樹的叫左斜樹,擁有右子樹的叫右斜樹。
3.滿二叉樹
滿二叉樹是所有的分支節點都存在左子樹和右子樹,并且所有葉子都在同一層的二叉樹。
4.完全二叉樹
對一顆具有n個節點的而擦汗數按層序編號,如果編號為i(1<=i<=n)的節點與同樣深度的滿二叉樹中編號為i的節點在二叉樹中位置完全相同,則這顆二叉樹就是完全二叉樹。完全二叉樹可以理解位連續的二叉樹。
5.二叉樹的性質
性質1:在二叉樹的第i層上至多有2^(i-1)個節點(i>=1)。
性質2:深度為k的二叉樹至多有2^k-1個節點(k>=1)。
性質3:對任何一顆二叉樹T,如果其終端節點數為n0,度為2的節點數為n1,則n0 = n1+1。
性質4:具有n個節點的完全二叉樹深度為log(2)(n)+1。
性質5:如果對一顆有n個節點的完全二叉樹的節點按層序編號(從第1層到第log(2)(n)+1層,每層從左到 右),對任意一個節點i(1<=i<=n)有:
如果i=1,則節點i是二叉樹的根,無雙親;如果i>1,則其雙親是結 點[i/2]
如果2i>n,則節點i無左孩子(節點i為葉子節點);否則其左孩 子是節點2i。
如果2i+1>n,則節點i無右孩子;否則其右孩子是節點2i+1。
6、二叉樹的實現
二叉樹有兩種實現方式:數組和鏈表。
三、二叉樹的遍歷
二叉樹有3種遍歷:
前序遍歷:規則是若二叉樹為空,則空操作返回,否則先訪問根節點,然后前序遍歷左子樹,再前序遍歷右子樹
中序遍歷:規則是若樹為空,則空操作返回,否則從根節點開始(注意并不是先訪問根節點),中序遍歷根節點的左子樹,然后是訪問根節點,最后中序遍歷右子樹
后序遍歷:規則是若樹為空,則空操作返回,否則從左到右先葉子后節點的方式遍歷訪問左右子樹,最后是訪問根節點
二叉樹的遍歷可以用遞歸和棧來實現。遞歸實現很簡單,但是棧實現也需要知道。
1.遞歸
/**
* 遞歸遍歷
*
* @param root 根節點
* @param type 遍歷方式:0代表前序,1代表中序,2代表后序
*/
public void ergodicRecursion(Node root, int type) {
if (root == null) {
return;
}
if (type == PREORDER) {
ToolShow.log("前序:" + root.toString());
}
ergodicRecursion(root.left, type);
if (type == INORDER) {
ToolShow.log("中序:" + root.toString());
}
ergodicRecursion(root.right, type);
if (type == AFTERORDER) {
ToolShow.log("后序:" + root.toString());
}
}
2.棧
/**
* 用棧遍歷
*
* @param curr 當前節點
* @param type 遍歷方式:0代表前序,1代表中序,2代表后序
*/
public void ergodicStack(Node curr, int type) {
//存放節點
Stack> stack = new Stack<>();
//記錄已經添加過的節點
List> nodeList = new ArrayList();
stack.push(curr);
nodeList.add(curr);
while (curr != null) {
//第一次遞歸之前:只執行一次
if (type == PREORDER && !nodeList.contains(curr.left) && !nodeList.contains(curr.right)) {
ToolShow.log("前序:" + curr.data);
}
//相當于第一次遞歸:已經添加過的節點不能重復添加
if (curr.left != null && !nodeList.contains(curr.left)) {
curr = curr.left;
stack.push(curr);
nodeList.add(curr);
} else {
//第二次遞歸之前:只執行一次
if (type == INORDER && !nodeList.contains(curr.right)) {
ToolShow.log("中序:" + curr.data);
}
//相當于第二次遞歸
if (curr.right != null && !nodeList.contains(curr.right)) {
curr = curr.right;
stack.push(curr);
nodeList.add(curr);
//兩次遞歸結束
} else {
if (type == AFTERORDER) {
ToolShow.log("后序:" + curr.data);
}
stack.pop();
curr = stack.isEmpty() ? null : stack.lastElement();
}
}
}
}
四、樹的轉換
1.樹轉二叉樹
加線。在所有兄弟節點之間就加一條連線。
去線。對樹中每一個節點,只保留它與第一個孩子節點的連線,刪除它與其他孩子節點之間的連線。
層次調整。以樹的根節點為軸心,將整棵樹順時針旋轉一定的角度,使之結構層次分明。注意第一個孩子是二叉樹節點的左孩子,兄弟轉換過來的孩子是節點的右孩子。
2.森林轉二叉樹
把每棵樹轉為二叉樹
第一棵二叉樹不動,從第二棵二叉樹開始,依次把后一棵二叉樹的根節點作為前一棵二叉樹的根節點的右孩子,用線連接起來。當所有的二叉樹連接起來后,就得到了右森林轉換的二叉樹。
3.二叉樹轉樹
加線。若某節點的左孩子存在,則將這個左孩子的右孩子、右孩子的右孩子、...,即這個左孩子的n個右孩子作為此節點的孩子。將該節點與這些右孩子節點用線連起來。
去線。刪除原二叉樹中所有節點與其右孩子節點的連線。
層次調整。使之層次分明。
4.二叉樹轉森林
判斷一顆二叉樹能轉換成一顆樹還是森林,只要看這顆二叉樹的根節點有沒有右孩子,有就是森林,沒有就是一棵樹。轉換森林的步驟如下:
從根節點開始,若有右孩子存在,則把與右孩子節點的連線刪除,再查看分離后的二叉樹,若右孩子存在,則連線刪除...,直到所有右孩子連線都刪除位置,得到分離的二叉樹。
再將每顆分離的二叉樹轉為樹即可。
最后
喜歡請點贊,謝謝!
總結
以上是生活随笔為你收集整理的android自定义绘制二叉树,安卓数据结构04-二叉树的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android自定义模态框,安卓开发自定
- 下一篇: android7.1开机监听广播,And