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

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

生活随笔

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

编程问答

【线索二叉树详解】数据结构06(java实现)

發(fā)布時(shí)間:2025/3/21 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【线索二叉树详解】数据结构06(java实现) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

線索二叉樹(shù)

1. 線索二叉樹(shù)簡(jiǎn)介

定義: 在二叉樹(shù)的結(jié)點(diǎn)上加上線索的二叉樹(shù)稱為線索二叉樹(shù)。

二叉樹(shù)的線索化: 對(duì)二叉樹(shù)以某種遍歷方式(如先序、中序、后序或?qū)哟蔚?#xff09;進(jìn)行遍歷,使其變?yōu)榫€索二叉樹(shù)的過(guò)程稱為對(duì)二叉樹(shù)進(jìn)行線索化。

現(xiàn)在我們來(lái)計(jì)算一下任意一顆二叉樹(shù)有多少個(gè)空的指針域

假設(shè)有n個(gè)結(jié)點(diǎn),一個(gè)結(jié)點(diǎn)有2個(gè)指針域(指向左右子節(jié)點(diǎn)),一共就有2n個(gè)結(jié)點(diǎn)

除了第一個(gè)結(jié)點(diǎn)不需要父節(jié)點(diǎn)指向,其余所有節(jié)點(diǎn)均需要指針,所以有n-1個(gè)已經(jīng)使用的指針域

剩下:2*n-(n-1)=n+1

結(jié)論:任意二叉樹(shù)的空余指針域?yàn)閚+1

如上圖所示:紅線就是將二叉樹(shù)線索化變成線索二叉樹(shù)的過(guò)程。

通俗的講:將普通二叉樹(shù)的空余指針域都利用起來(lái),指向其前驅(qū)結(jié)點(diǎn)或后繼結(jié)點(diǎn)就變成了線索二叉樹(shù)

2. 線索二叉樹(shù)的實(shí)現(xiàn)

2.1 實(shí)現(xiàn)思路

首先我們需要選擇線索化二叉樹(shù)的方式-這里我們使用中序線索化二叉樹(shù)

在遍歷每個(gè)節(jié)點(diǎn)時(shí),判斷結(jié)點(diǎn)的左子節(jié)點(diǎn)和右子節(jié)點(diǎn)是否為空(也就是左右指針域)

如果左子節(jié)點(diǎn)為空就將其指向當(dāng)前結(jié)點(diǎn)的前驅(qū)結(jié)點(diǎn)

如果右子節(jié)點(diǎn)為空就指向后繼結(jié)點(diǎn)(這里的前驅(qū)、后繼結(jié)點(diǎn)是相對(duì)于遍歷方式而言)

相比普通二叉樹(shù)我們?cè)黾觾蓚€(gè)標(biāo)志位:leftType、rightType

2.2 實(shí)現(xiàn)代碼

二叉樹(shù)結(jié)點(diǎn)類:ThreadedBinaryNode.java

//中序線索二叉樹(shù) public class ThreadedBinaryNode {//結(jié)點(diǎn)的值int value;//左節(jié)點(diǎn)ThreadedBinaryNode leftNode;//右節(jié)點(diǎn)ThreadedBinaryNode rightNode;//線索二叉樹(shù)增加的兩個(gè)屬性//1代表存儲(chǔ)的是前驅(qū)、后續(xù)結(jié)點(diǎn)。0代表左右兒子(默認(rèn)為0)int leftType,rightType;//初始化值public ThreadedBinaryNode(int value){this.value=value;}//設(shè)置左節(jié)點(diǎn)public void setLeftNode(ThreadedBinaryNode leftNode) {this.leftNode = leftNode;}//設(shè)置右節(jié)點(diǎn)public void setRightNode(ThreadedBinaryNode rightNode) {this.rightNode = rightNode;} }

線索二叉樹(shù)類:ThreadedBinaryTree.java

增加了一個(gè)存儲(chǔ)前驅(qū)結(jié)點(diǎn)的pre,主要實(shí)現(xiàn)中序線索化的threadedMid方法,遍歷方法threadedIterate

public class ThreadedBinaryTree {//根節(jié)點(diǎn)ThreadedBinaryNode root;//存儲(chǔ)前序結(jié)點(diǎn)ThreadedBinaryNode pre=null;//設(shè)置根節(jié)點(diǎn)、獲取根節(jié)點(diǎn)public ThreadedBinaryNode getRoot() {return root;}public void setRoot(ThreadedBinaryNode root) {this.root = root;}//遍歷中序化線索二叉樹(shù)public void threadedIterate(){ThreadedBinaryNode node=root;while(node!=null){//先找到中序遍歷最左邊的結(jié)點(diǎn)while(node.leftType==0){node=node.leftNode;}System.out.print(node.value+" ");//遍歷右指針域指向后繼基點(diǎn)的結(jié)點(diǎn)while(node.rightType==1){node=node.rightNode;System.out.print(node.value+" ");}//替換遍歷結(jié)點(diǎn)node=node.rightNode;}}//方便調(diào)用public void threadedMid(){threadedMid(root);}//中序線索化二叉樹(shù)-將左右指針域?yàn)榭盏臉?biāo)記1,不為空(指向左右兒子)的默認(rèn)為0public void threadedMid(ThreadedBinaryNode node){if(node==null)return;//遞歸處理左子樹(shù)threadedMid(node.leftNode);//處理當(dāng)前結(jié)點(diǎn)的左指針域if(node.leftNode==null){//將當(dāng)前結(jié)點(diǎn)的左指針域指向前序結(jié)點(diǎn)node.leftNode=pre;//標(biāo)記node.leftType=1;}//處理前驅(qū)結(jié)點(diǎn)pre的右指針域//因?yàn)檫@里拿不到當(dāng)前結(jié)點(diǎn)的下一個(gè)結(jié)點(diǎn),所以不能處理當(dāng)前節(jié)點(diǎn)的右指針域if(pre!=null&&pre.rightNode==null){//如果pre的右指針為空,就指向他的后繼結(jié)點(diǎn)-nodepre.rightNode=node;pre.rightType=1;}//保存當(dāng)前結(jié)點(diǎn),為下一結(jié)點(diǎn)的prepre=node;//遞歸處理右子樹(shù)threadedMid(node.rightNode);} }

測(cè)試類

public class TestThreadedTree {public static void main(String[] args) {//創(chuàng)建一顆空二叉樹(shù)ThreadedBinaryTree threadedBinaryTree = new ThreadedBinaryTree();//創(chuàng)建根結(jié)點(diǎn)ThreadedBinaryNode root=new ThreadedBinaryNode(1);threadedBinaryTree.setRoot(root);//創(chuàng)建根結(jié)點(diǎn)的左節(jié)點(diǎn)和右節(jié)點(diǎn)ThreadedBinaryNode leftNode = new ThreadedBinaryNode(2);ThreadedBinaryNode rightNode = new ThreadedBinaryNode(3);//將左右結(jié)點(diǎn)連接在根結(jié)點(diǎn)后root.setLeftNode(leftNode);root.setRightNode(rightNode);//增加四個(gè)節(jié)點(diǎn) 4、5、6、7方便遍歷leftNode.setLeftNode(new ThreadedBinaryNode(4));leftNode.setRightNode(new ThreadedBinaryNode(5));rightNode.setLeftNode(new ThreadedBinaryNode(6));rightNode.setRightNode(new ThreadedBinaryNode(7));//中序線索化二叉樹(shù)threadedBinaryTree.threadedMid();//遍歷中序線索二叉樹(shù)System.out.println("遍歷中序線索二叉樹(shù)結(jié)果為:");threadedBinaryTree.threadedIterate();} }

結(jié)果:

遍歷中序線索二叉樹(shù)結(jié)果為: 4 2 5 1 6 3 7

3. 總結(jié):

線索二叉樹(shù)減少了的空指針域的同時(shí)又對(duì)每個(gè)節(jié)點(diǎn)增加了兩個(gè)標(biāo)志位。好處:在遍歷時(shí)不需要使用遞歸,相比普通二叉樹(shù)遍歷效率更高在查找前驅(qū)/后繼結(jié)點(diǎn)時(shí)更加高效

4. 應(yīng)用

當(dāng)路由器使用CIDR,選擇下一跳的時(shí)候,或者轉(zhuǎn)發(fā)分組的時(shí)候,通常會(huì)用最長(zhǎng)前綴匹配(最佳匹配)來(lái)得到路由表的一行數(shù)據(jù),為了更加有效的查找最長(zhǎng)前綴匹配,通常使用的數(shù)據(jù)結(jié)構(gòu)為二叉線索。

總結(jié)

以上是生活随笔為你收集整理的【线索二叉树详解】数据结构06(java实现)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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