遍历线索化二叉树+图解
生活随笔
收集整理的這篇文章主要介紹了
遍历线索化二叉树+图解
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
圖解
代碼實現
package com.atguigu.tree.threadedbinarytree;/*** @創建人 wdl* @創建時間 2021/3/25* @描述*/ public class ThreadedBinaryTreeDemo {public static void main(String[] args) {//測試一把中序線索化二叉樹的功能HeroNode root = new HeroNode(1, "tom");HeroNode node2 = new HeroNode(3, "jack");HeroNode node3 = new HeroNode(6, "smith");HeroNode node4 = new HeroNode(8, "mary");HeroNode node5 = new HeroNode(10, "king");HeroNode node6 = new HeroNode(14, "dim");//二叉樹,后面我們需要遞歸創建,現在手動創建root.setLeft(node2);root.setRight(node3);node2.setLeft(node4);node2.setRight(node5);node3.setLeft(node6);//測試中序線索化ThreadedBinaryTree threadedBinaryTree = new ThreadedBinaryTree();threadedBinaryTree.setRoot(root);threadedBinaryTree.threadedNodes();//測試:以10號節點測試HeroNode leftNode = node5.getLeft();HeroNode rightNode = node5.getRight();System.out.println("10號節點的前驅節點是"+leftNode);System.out.println("10號節點的后繼節點是"+rightNode);//當線索化二叉樹后System.out.println("使用線索化的方式遍歷 線索化二叉樹");threadedBinaryTree.threadedList();//8,3,10,1,14,6}}//定義ThreadedBinaryTree實現了線索化功能的二叉樹 class ThreadedBinaryTree{private HeroNode root;//為了實現線索化,需要創建一個指向當前節點的前驅節點的指針//在遞歸進行線索化是,pre總是保留前一個節點private HeroNode pre=null;public void setRoot(HeroNode root){this.root=root;}//重載threadedNodes方法public void threadedNodes(){this.threadedNodes(root);}//遍歷線索化二叉樹的方法public void threadedList(){//定義一個變量,存儲當前遍歷的節點,從root開始HeroNode node=root;while (node!=null){//循環的扎到leftType==1的節點,第一個找到的就是8節點//后面會隨著遍歷而變化,因為當lefType==1時,說明該節點是按照線索化//處理后的有效節點while (node.getLeftType()==0){node=node.getLeft();}//打印當前的節點System.out.println(node);//如果當前節點的右指針指向的是后繼節點,就一直輸出while (node.getRightType()==1){//獲取到當前節點的后繼節點node=node.getRight();System.out.println(node);}//替換這個遍歷的節點node=node.getRight();}}//編寫對二叉樹進行中序線索化的方法/**** @param node 就是當前需要線索化的節點*/public void threadedNodes(HeroNode node){//如果node==null,不能線索化if(node==null){return;}//1.先線索化左子樹threadedNodes(node.getLeft());//2.線索化當前節點[有難度]//處理當前節點的前驅節點//以8節點來理解//8節點的.left=null,8節點的.leftType=1if(node.getLeft()==null){//當前節點的左指針指向前驅節點node.setLeft(pre);//修改當前節點的左指針的類型,指向前驅節點node.setLeftType(1);}//處理當前節點的后繼節點if(pre!=null&&pre.getRight()==null){//讓前驅節點的右指針指向當前節點pre.setRight(node);//修改前驅節點的右指針類型pre.setRightType(1);}//!!!每處理一個節點,讓當前節點是下一個節點的前驅節點pre=node;//3.再線索化右子樹threadedNodes(node.getRight());}//刪除節點public void delNode(int no){if(root!=null){//如果只有一個root接地那,這里立即判斷root是不是就是要刪除的節點if(root.getNo()==no){root=null;}else {//遞歸刪除root.delNode(no);}}else {System.out.println("空樹,不能刪除");}}//前序遍歷public void preOrder(){if(this.root!=null){this.root.preOrder();}else {System.out.println("二叉樹為空,無法遍歷");}}//中序遍歷public void infixOrder(){if(this.root!=null){this.root.infixOrder();}else {System.out.println("二叉樹為空,無法遍歷");}}//后序遍歷public void postOrder(){if(this.root!=null){this.root.postOrder();}else {System.out.println("二叉樹為空,無法遍歷");}}//前序查找public HeroNode preOrderSearch(int no){if(root!=null){return root.preOrderSearch(no);}else {return null;}}//中序查找public HeroNode infixOrderSearch(int no){if(root!=null){return root.infixOrderSearch(no);}else {return null;}}//后序查找public HeroNode postOrderSearch(int no){if(root!=null){return root.postOrderSearch(no);}else {return null;}}}//先創建HeroNode節點 class HeroNode{private int no;private String name;private HeroNode left;//默認為nullprivate HeroNode right;//默認為null//說明//1.如果leftType==0表示指向的是左子樹,如果是1則表示指向前驅節點//2.如果rightType==0表示指向的是右子樹,如果是1則表示指向后繼節點private int leftType;private int rightType;public int getLeftType() {return leftType;}public void setLeftType(int leftType) {this.leftType = leftType;}public int getRightType() {return rightType;}public void setRightType(int rightType) {this.rightType = rightType;}public HeroNode(int no, String name) {super();this.no = no;this.name = name;}public int getNo() {return no;}public void setNo(int no) {this.no = no;}public String getName() {return name;}public void setName(String name) {this.name = name;}public HeroNode getLeft() {return left;}public void setLeft(HeroNode left) {this.left = left;}public HeroNode getRight() {return right;}public void setRight(HeroNode right) {this.right = right;}@Overridepublic String toString() {return "HeroNode{" +"no=" + no +", name='" + name + '\'' +'}';}//遞歸刪除節點//1.如果刪除的節點是葉子節點,則刪除該節點//2.如果刪除的節點是非葉子節點,則刪除該子樹public void delNode(int no){if(this.left!=null&&this.left.no==no){this.left=null;return;}if(this.right!=null&&this.right.no==no){this.right=null;return;}if(this.left!=null){this.left.delNode(no);}if(this.right!=null){this.right.delNode(no);}}//編寫前序遍歷的方法public void preOrder(){System.out.println(this);//先輸出父節點//遞歸向左子樹前序遍歷if(this.left!=null){this.left.preOrder();}//遞歸向右子樹前序遍歷if(this.right!=null){this.right.preOrder();}}//中序遍歷public void infixOrder(){//遞歸向左子樹中序遍歷if(this.left!=null){this.left.infixOrder();}System.out.println(this);//輸出父節點//遞歸向右子樹中序遍歷if(this.right!=null){this.right.infixOrder();}}//后序遍歷public void postOrder(){//遞歸向左子樹后序遍歷if(this.left!=null){this.left.postOrder();}//遞歸向右子樹后序遍歷if(this.right!=null){this.right.postOrder();}System.out.println(this);//輸出父節點}/**** @param no 查找no* @return 如果找到就返回該Node,如果沒有找到返回null*///前序遍歷查找public HeroNode preOrderSearch(int no){System.out.println("進入前序查找");//比較當前節點是不是if(this.no==no){return this;}//1.則判斷當前節點的左子節點是否為空,如果不為空,則遞歸前序查找//2.如果左遞歸前序查找,找到節點,則返回HeroNode resNode=null;if(this.left!=null){resNode=this.left.preOrderSearch(no);}if(resNode!=null){//說明我們左子樹找到return resNode;}//1.左遞歸前序查找,找到節點,則返回,否則判斷//2.當前的節點的右子節點是否為空,如果不空,則繼續向右遞歸前序查找if(this.right!=null){resNode=this.right.preOrderSearch(no);}return resNode;}//中序遍歷查找public HeroNode infixOrderSearch(int no){//判斷當前節點的左子節點是否為空,如果不為空,則遞歸中序查找HeroNode resNode=null;if(this.left!=null){resNode=this.left.infixOrderSearch(no);}if(resNode!=null){//說明我們左子樹找到return resNode;}System.out.println("進入中序查找");//如果找到,則返回,如果沒有找到,就和當前節點比較,如果是則返回當前節點if(this.no==no){return this;}//否則繼續進行右遞歸的中序查找if(this.right!=null){resNode=this.right.infixOrderSearch(no);}return resNode;}//后序遍歷查找public HeroNode postOrderSearch(int no){//判斷當前節點的左子節點是否為空,如果不為空,則遞歸中序查找HeroNode resNode=null;if(this.left!=null){resNode=this.left.postOrderSearch(no);}if(resNode!=null){//說明我們左子樹找到return resNode;}//如果左子樹沒有找到,則向右子樹遞歸進行后序遍歷查找if(this.right!=null){resNode=this.right.postOrderSearch(no);}if(resNode!=null){//說明我們右子樹找到return resNode;}System.out.println("進入后序遍歷");//如果左右子樹都沒有找到,就比較當前節點是不是if(this.no==no){return this;}return resNode;}}總結
以上是生活随笔為你收集整理的遍历线索化二叉树+图解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 显卡知识科普大全电脑显卡知识大全
- 下一篇: 堆排序代码实现