日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

android自定义绘制二叉树,安卓数据结构04-二叉树

發布時間:2024/10/8 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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-二叉树的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。