日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

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

發(fā)布時(shí)間:2024/10/8 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android自定义绘制二叉树,安卓数据结构04-二叉树 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

數(shù)據(jù)結(jié)構(gòu)04-二叉樹(shù)

一、樹(shù)的基本概念

1.樹(shù)

樹(shù)是n(n>=0)個(gè)節(jié)點(diǎn)的有限集。n=0時(shí)稱(chēng)為空樹(shù)。在任意一顆非空樹(shù)中:

有且僅有一個(gè)特定的稱(chēng)為根(Root)的節(jié)點(diǎn);

當(dāng)n>1時(shí),其余節(jié)點(diǎn)可分為m(m>0)個(gè)互不相交的有限集T1、T2、......、Tm,其中每一個(gè)集合本事又是一顆樹(shù),并且稱(chēng)為根的子樹(shù)(SubTree)。

2.度

節(jié)點(diǎn)的度是節(jié)點(diǎn)擁有的子樹(shù)數(shù)。度為0的節(jié)點(diǎn)稱(chēng)為葉子節(jié)點(diǎn)或終端節(jié)點(diǎn),度不為0的節(jié)點(diǎn)稱(chēng)為非終端節(jié)點(diǎn)或分支節(jié)點(diǎn)。除根節(jié)點(diǎn)以外,分支節(jié)點(diǎn)也稱(chēng)為內(nèi)部節(jié)點(diǎn)。樹(shù)的度是樹(shù)內(nèi)各節(jié)點(diǎn)的度的最大值。

3.層次

節(jié)點(diǎn)的層次(Level)從根開(kāi)始定義起,根為第一層,根的孩子為第二層。若某節(jié)點(diǎn)在第n層,則其字?jǐn)?shù)的根就在第n+1層。其雙親在同一層的節(jié)點(diǎn)互為堂兄弟。樹(shù)中節(jié)點(diǎn)的最大層次稱(chēng)為樹(shù)的深度(Depth)或高度。

4.森林

森林(Forest)是m(m>=0)棵互不相交的集合。

5.樹(shù)的存儲(chǔ)結(jié)構(gòu)

簡(jiǎn)單的順序存儲(chǔ)不能滿(mǎn)足樹(shù)的實(shí)現(xiàn),一般結(jié)合順序存儲(chǔ)和鏈?zhǔn)酱鎯?chǔ)來(lái)實(shí)現(xiàn),有四種表示方法:

雙親表示法:在每個(gè)節(jié)點(diǎn)中,附設(shè)一個(gè)指示器指示其雙親節(jié)點(diǎn)到鏈表中的位置。

孩子表示法:在每個(gè)節(jié)點(diǎn)中,附設(shè)幾個(gè)指示器指示子節(jié)點(diǎn)到鏈表中的位置。

雙親孩子表示法:在每個(gè)節(jié)點(diǎn)中,附設(shè)2個(gè)指示器,一個(gè)指示雙親節(jié)點(diǎn),一個(gè)指示孩子鏈表(由它的孩子節(jié)點(diǎn)組成的單鏈表)。

孩子兄弟表示法:在每個(gè)節(jié)點(diǎn)中,附設(shè)2個(gè)指示器,一個(gè)指示它的第一個(gè)孩子節(jié)點(diǎn),一個(gè)指向它的下一個(gè)兄弟節(jié)點(diǎn)。

二、二叉樹(shù)的基本概念

1.二叉樹(shù)

二叉樹(shù)(Binary Tree)是n(n>=0)個(gè)節(jié)點(diǎn)的有限集合,該集合或者位空集(稱(chēng)為空二叉樹(shù)),或者有一個(gè)根節(jié)點(diǎn)和兩顆互不相交的、分別稱(chēng)為根節(jié)點(diǎn)的左子樹(shù)和右子樹(shù)的二叉樹(shù)組成。

2.斜樹(shù)

斜樹(shù)是所有的節(jié)點(diǎn)都只有左子樹(shù)或右子樹(shù)的二叉樹(shù),擁有左子樹(shù)的叫左斜樹(shù),擁有右子樹(shù)的叫右斜樹(shù)。

3.滿(mǎn)二叉樹(shù)

滿(mǎn)二叉樹(shù)是所有的分支節(jié)點(diǎn)都存在左子樹(shù)和右子樹(shù),并且所有葉子都在同一層的二叉樹(shù)。

4.完全二叉樹(shù)

對(duì)一顆具有n個(gè)節(jié)點(diǎn)的而擦汗數(shù)按層序編號(hào),如果編號(hào)為i(1<=i<=n)的節(jié)點(diǎn)與同樣深度的滿(mǎn)二叉樹(shù)中編號(hào)為i的節(jié)點(diǎn)在二叉樹(shù)中位置完全相同,則這顆二叉樹(shù)就是完全二叉樹(shù)。完全二叉樹(shù)可以理解位連續(xù)的二叉樹(shù)。

5.二叉樹(shù)的性質(zhì)

性質(zhì)1:在二叉樹(shù)的第i層上至多有2^(i-1)個(gè)節(jié)點(diǎn)(i>=1)。

性質(zhì)2:深度為k的二叉樹(shù)至多有2^k-1個(gè)節(jié)點(diǎn)(k>=1)。

性質(zhì)3:對(duì)任何一顆二叉樹(shù)T,如果其終端節(jié)點(diǎn)數(shù)為n0,度為2的節(jié)點(diǎn)數(shù)為n1,則n0 = n1+1。

性質(zhì)4:具有n個(gè)節(jié)點(diǎn)的完全二叉樹(shù)深度為log(2)(n)+1。

性質(zhì)5:如果對(duì)一顆有n個(gè)節(jié)點(diǎn)的完全二叉樹(shù)的節(jié)點(diǎn)按層序編號(hào)(從第1層到第log(2)(n)+1層,每層從左到 右),對(duì)任意一個(gè)節(jié)點(diǎn)i(1<=i<=n)有:

如果i=1,則節(jié)點(diǎn)i是二叉樹(shù)的根,無(wú)雙親;如果i>1,則其雙親是結(jié) 點(diǎn)[i/2]

如果2i>n,則節(jié)點(diǎn)i無(wú)左孩子(節(jié)點(diǎn)i為葉子節(jié)點(diǎn));否則其左孩 子是節(jié)點(diǎn)2i。

如果2i+1>n,則節(jié)點(diǎn)i無(wú)右孩子;否則其右孩子是節(jié)點(diǎn)2i+1。

6、二叉樹(shù)的實(shí)現(xiàn)

二叉樹(shù)有兩種實(shí)現(xiàn)方式:數(shù)組和鏈表。

三、二叉樹(shù)的遍歷

二叉樹(shù)有3種遍歷:

前序遍歷:規(guī)則是若二叉樹(shù)為空,則空操作返回,否則先訪問(wèn)根節(jié)點(diǎn),然后前序遍歷左子樹(shù),再前序遍歷右子樹(shù)

中序遍歷:規(guī)則是若樹(shù)為空,則空操作返回,否則從根節(jié)點(diǎn)開(kāi)始(注意并不是先訪問(wèn)根節(jié)點(diǎn)),中序遍歷根節(jié)點(diǎn)的左子樹(shù),然后是訪問(wèn)根節(jié)點(diǎn),最后中序遍歷右子樹(shù)

后序遍歷:規(guī)則是若樹(shù)為空,則空操作返回,否則從左到右先葉子后節(jié)點(diǎn)的方式遍歷訪問(wèn)左右子樹(shù),最后是訪問(wèn)根節(jié)點(diǎn)

二叉樹(shù)的遍歷可以用遞歸和棧來(lái)實(shí)現(xiàn)。遞歸實(shí)現(xiàn)很簡(jiǎn)單,但是棧實(shí)現(xiàn)也需要知道。

1.遞歸

/**

* 遞歸遍歷

*

* @param root 根節(jié)點(diǎn)

* @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 當(dāng)前節(jié)點(diǎn)

* @param type 遍歷方式:0代表前序,1代表中序,2代表后序

*/

public void ergodicStack(Node curr, int type) {

//存放節(jié)點(diǎn)

Stack> stack = new Stack<>();

//記錄已經(jīng)添加過(guò)的節(jié)點(diǎn)

List> nodeList = new ArrayList();

stack.push(curr);

nodeList.add(curr);

while (curr != null) {

//第一次遞歸之前:只執(zhí)行一次

if (type == PREORDER && !nodeList.contains(curr.left) && !nodeList.contains(curr.right)) {

ToolShow.log("前序:" + curr.data);

}

//相當(dāng)于第一次遞歸:已經(jīng)添加過(guò)的節(jié)點(diǎn)不能重復(fù)添加

if (curr.left != null && !nodeList.contains(curr.left)) {

curr = curr.left;

stack.push(curr);

nodeList.add(curr);

} else {

//第二次遞歸之前:只執(zhí)行一次

if (type == INORDER && !nodeList.contains(curr.right)) {

ToolShow.log("中序:" + curr.data);

}

//相當(dāng)于第二次遞歸

if (curr.right != null && !nodeList.contains(curr.right)) {

curr = curr.right;

stack.push(curr);

nodeList.add(curr);

//兩次遞歸結(jié)束

} else {

if (type == AFTERORDER) {

ToolShow.log("后序:" + curr.data);

}

stack.pop();

curr = stack.isEmpty() ? null : stack.lastElement();

}

}

}

}

四、樹(shù)的轉(zhuǎn)換

1.樹(shù)轉(zhuǎn)二叉樹(shù)

加線。在所有兄弟節(jié)點(diǎn)之間就加一條連線。

去線。對(duì)樹(shù)中每一個(gè)節(jié)點(diǎn),只保留它與第一個(gè)孩子節(jié)點(diǎn)的連線,刪除它與其他孩子節(jié)點(diǎn)之間的連線。

層次調(diào)整。以樹(shù)的根節(jié)點(diǎn)為軸心,將整棵樹(shù)順時(shí)針旋轉(zhuǎn)一定的角度,使之結(jié)構(gòu)層次分明。注意第一個(gè)孩子是二叉樹(shù)節(jié)點(diǎn)的左孩子,兄弟轉(zhuǎn)換過(guò)來(lái)的孩子是節(jié)點(diǎn)的右孩子。

2.森林轉(zhuǎn)二叉樹(shù)

把每棵樹(shù)轉(zhuǎn)為二叉樹(shù)

第一棵二叉樹(shù)不動(dòng),從第二棵二叉樹(shù)開(kāi)始,依次把后一棵二叉樹(shù)的根節(jié)點(diǎn)作為前一棵二叉樹(shù)的根節(jié)點(diǎn)的右孩子,用線連接起來(lái)。當(dāng)所有的二叉樹(shù)連接起來(lái)后,就得到了右森林轉(zhuǎn)換的二叉樹(shù)。

3.二叉樹(shù)轉(zhuǎn)樹(shù)

加線。若某節(jié)點(diǎn)的左孩子存在,則將這個(gè)左孩子的右孩子、右孩子的右孩子、...,即這個(gè)左孩子的n個(gè)右孩子作為此節(jié)點(diǎn)的孩子。將該節(jié)點(diǎn)與這些右孩子節(jié)點(diǎn)用線連起來(lái)。

去線。刪除原二叉樹(shù)中所有節(jié)點(diǎn)與其右孩子節(jié)點(diǎn)的連線。

層次調(diào)整。使之層次分明。

4.二叉樹(shù)轉(zhuǎn)森林

判斷一顆二叉樹(shù)能轉(zhuǎn)換成一顆樹(shù)還是森林,只要看這顆二叉樹(shù)的根節(jié)點(diǎn)有沒(méi)有右孩子,有就是森林,沒(méi)有就是一棵樹(shù)。轉(zhuǎn)換森林的步驟如下:

從根節(jié)點(diǎn)開(kāi)始,若有右孩子存在,則把與右孩子節(jié)點(diǎn)的連線刪除,再查看分離后的二叉樹(shù),若右孩子存在,則連線刪除...,直到所有右孩子連線都刪除位置,得到分離的二叉樹(shù)。

再將每顆分離的二叉樹(shù)轉(zhuǎn)為樹(shù)即可。

最后

喜歡請(qǐng)點(diǎn)贊,謝謝!

總結(jié)

以上是生活随笔為你收集整理的android自定义绘制二叉树,安卓数据结构04-二叉树的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。