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