java线索二叉树的实现_JAVA递归实现线索化二叉树
JAVA遞歸實(shí)現(xiàn)線索化二叉樹
基礎(chǔ)理論
首先,二叉樹遞歸遍歷分為先序遍歷、中序遍歷和后序遍歷。
先序遍歷為:根節(jié)點(diǎn)+左子樹+右子樹
中序遍歷為:左子樹+根節(jié)點(diǎn)+右子樹
后序遍歷為:左子樹+右子樹+根節(jié)點(diǎn)
(只要記住根節(jié)點(diǎn)在哪里就是什么遍歷,且都是先左再右)
線索化
現(xiàn)在有這么一棵二叉樹,它的數(shù)據(jù)結(jié)構(gòu)由左節(jié)點(diǎn)+權(quán)+右節(jié)點(diǎn)構(gòu)成。
可以看到4,5,6,7這幾個(gè)節(jié)點(diǎn)的左右節(jié)點(diǎn)空間被浪費(fèi)了。因此,線索化是指有效利用這些空間。
中序遍歷的順序?yàn)?#xff1a;4 2 5 1 6 3 7
現(xiàn)在引入前驅(qū)節(jié)點(diǎn)以及后繼節(jié)點(diǎn)。
前驅(qū)節(jié)點(diǎn):線索化二叉樹時(shí),一個(gè)節(jié)點(diǎn)的前一個(gè)節(jié)點(diǎn)
后繼節(jié)點(diǎn):線索化二叉樹時(shí),一個(gè)節(jié)點(diǎn)的后一個(gè)節(jié)點(diǎn)
(例如下圖:根據(jù)中序遍歷,5的前驅(qū)節(jié)點(diǎn)是2 , 5的后繼節(jié)點(diǎn)是1)
(中序遍歷)實(shí)現(xiàn)線索化二叉樹
定義數(shù)據(jù)結(jié)構(gòu)ThreadedNode
//節(jié)點(diǎn)的權(quán)
int value;
//左兒子
ThreadedNode leftNode;
//右兒子
ThreadedNode rightNode;
//標(biāo)識(shí)指針類型,其中0,1分別表示有無(wú)線索化,默認(rèn)為0
int leftType;
int rightType;
中序遍歷
//中序遍歷
public void midShow() {
//左子節(jié)點(diǎn)
if(leftNode!=null) {
leftNode.midShow();
}
//當(dāng)前節(jié)點(diǎn)
System.out.println(value);
//右子節(jié)點(diǎn)
if(rightNode!=null) {
rightNode.midShow();
}
}
這里使用遞歸的方式來(lái)實(shí)現(xiàn)。我們先把問(wèn)題簡(jiǎn)單化,只看紅圈的部分,如下圖
定義一個(gè)節(jié)點(diǎn)pre用來(lái)存儲(chǔ)當(dāng)前節(jié)點(diǎn),類似指針。
從根節(jié)點(diǎn)1開始遞歸,如果當(dāng)前節(jié)點(diǎn)為空,返回,到4,此時(shí)4的前驅(qū)結(jié)點(diǎn)為null,結(jié)點(diǎn)5的前驅(qū)結(jié)點(diǎn)為2
遍歷到5的時(shí)候指向前驅(qū)結(jié)點(diǎn)2,前驅(qū)結(jié)點(diǎn)2為上一層遞歸的指針,因此指向它的前驅(qū)結(jié)點(diǎn)就行,再把左指針類型置為1
如果當(dāng)前節(jié)點(diǎn)的前驅(qū)結(jié)點(diǎn)pre的右指針為null,則將它設(shè)置為當(dāng)前節(jié)點(diǎn),此時(shí)即4的后繼結(jié)點(diǎn)為2,并將右指針類型置為1
每處理一個(gè)節(jié)點(diǎn),當(dāng)前節(jié)點(diǎn)是下一個(gè)節(jié)點(diǎn)的前驅(qū)節(jié)點(diǎn)
線索化二叉樹ThreadedBinaryTree
//中序線索化二叉樹
public void threadNodes() {
threadNodes(root);
}
public void threadNodes(ThreadedNode node) {
//當(dāng)前節(jié)點(diǎn)如果為null,直接返回
if(node==null) {
return;
}
//處理前驅(qū)節(jié)點(diǎn)
if(node.leftNode==null){
//讓當(dāng)前節(jié)點(diǎn)的左指針指向前驅(qū)節(jié)點(diǎn)
node.leftNode=pre;
//改變當(dāng)前節(jié)點(diǎn)左指針的類型
node.leftType=1;
}
//處理前驅(qū)的右指針,如果前驅(qū)節(jié)點(diǎn)的右指針是null(沒(méi)有指下右子樹)
if(pre!=null&&pre.rightNode==null) {
//讓前驅(qū)節(jié)點(diǎn)的右指針指向當(dāng)前節(jié)點(diǎn)
pre.rightNode=node;
//改變前驅(qū)節(jié)點(diǎn)的右指針類型
pre.rightType=1;
}
//每處理一個(gè)節(jié)點(diǎn),當(dāng)前節(jié)點(diǎn)是下一個(gè)節(jié)點(diǎn)的前驅(qū)節(jié)點(diǎn)
pre=node;
}
現(xiàn)在再把上面這段代碼按照中序遍歷的方式放在中間,進(jìn)行遞歸
//當(dāng)前節(jié)點(diǎn)如果為null,直接返回
if(node==null) {
return;
}
//處理左子樹
threadNodes(node.leftNode);
//----------------------------------------------------------
//處理前驅(qū)節(jié)點(diǎn)
if(node.leftNode==null){
//讓當(dāng)前節(jié)點(diǎn)的左指針指向前驅(qū)節(jié)點(diǎn)
node.leftNode=pre;
//改變當(dāng)前節(jié)點(diǎn)左指針的類型
node.leftType=1;
}
//處理前驅(qū)的右指針,如果前驅(qū)節(jié)點(diǎn)的右指針是null(沒(méi)有指下右子樹)
if(pre!=null&&pre.rightNode==null) {
//讓前驅(qū)節(jié)點(diǎn)的右指針指向當(dāng)前節(jié)點(diǎn)
pre.rightNode=node;
//改變前驅(qū)節(jié)點(diǎn)的右指針類型
pre.rightType=1;
}
//每處理一個(gè)節(jié)點(diǎn),當(dāng)前節(jié)點(diǎn)是下一個(gè)節(jié)點(diǎn)的前驅(qū)節(jié)點(diǎn)
pre=node;
//-----------------------------------------------------------
//處理右子樹
threadNodes(node.rightNode);
}
現(xiàn)在編寫測(cè)試方法
package demo7;
public class TestThreadedBinaryTree {
public static void main(String[] args) {
//創(chuàng)建一顆樹
ThreadedBinaryTree binTree = new ThreadedBinaryTree();
//創(chuàng)建一個(gè)根節(jié)點(diǎn)
ThreadedNode root = new ThreadedNode(1);
//把根節(jié)點(diǎn)賦給樹
binTree.setRoot(root);
//創(chuàng)建一個(gè)左節(jié)點(diǎn)
ThreadedNode rootL = new ThreadedNode(2);
//把新創(chuàng)建的節(jié)點(diǎn)設(shè)置為根節(jié)點(diǎn)的子節(jié)點(diǎn)
root.setLeftNode(rootL);
//創(chuàng)建一個(gè)右節(jié)點(diǎn)
ThreadedNode rootR = new ThreadedNode(3);
//把新創(chuàng)建的節(jié)點(diǎn)設(shè)置為根節(jié)點(diǎn)的子節(jié)點(diǎn)
root.setRightNode(rootR);
//為第二層的左節(jié)點(diǎn)創(chuàng)建兩個(gè)子節(jié)點(diǎn)
rootL.setLeftNode(new ThreadedNode(4));
ThreadedNode fiveNode = new ThreadedNode(5);
rootL.setRightNode(fiveNode);
//為第二層的右節(jié)點(diǎn)創(chuàng)建兩個(gè)子節(jié)點(diǎn)
rootR.setLeftNode(new ThreadedNode(6));
rootR.setRightNode(new ThreadedNode(7));
//中序遍歷樹
binTree.midShow();
System.out.println("===============");
//中前線索化二叉樹
binTree.threadNodes();
binTree.threadIterate();
}
}
與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的java线索二叉树的实现_JAVA递归实现线索化二叉树的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: java反序列化漏洞 tomcat_CV
- 下一篇: 微信小程序支付java视频_【原创】微信