二叉树的线索化及遍历(前序、中叙、后序)Java版

这篇博客介绍了如何使用Java实现线索二叉树,并分别进行前序、中序和后序线索化。代码详细展示了线索化过程以及对应的线索化遍历方法,有助于理解线索二叉树的概念。

啥都不说了,直接上代码,可能比较乱,但是也是非常清晰的。

package com.zk.datastruct.tree;

import lombok.Data;

public class ThreadedBinaryTreeDemo {

    public static void main(String[] args) {
        ThreadedTreeNode root = getTree();
        ThreadedTree tree = new ThreadedTree(root);

//        tree.midThreadedNodes(root);
//        tree.listMidThreadedNodes();

//        tree.preThreadedNodes(root);
//        tree.listPreThreadedNodes();

        tree.postThreadedNodes(root);
        tree.listPostThreadedNodes(root);

    }

    public static ThreadedTreeNode getTree(){
        ThreadedTreeNode node1 = new ThreadedTreeNode(1);
        ThreadedTreeNode node2 = new ThreadedTreeNode(2);
        ThreadedTreeNode node3 = new ThreadedTreeNode(3);
        ThreadedTreeNode node4 = new ThreadedTreeNode(4);
        ThreadedTreeNode node5 = new ThreadedTreeNode(5);
        ThreadedTreeNode node6 = new ThreadedTreeNode(6);
        ThreadedTreeNode node7 = new ThreadedTreeNode(7);

        node1.setLeft(node2);
        node1.setRight(node3);

        node2.setLeft(node4);
        node2.setRight(node5);

        node3.setLeft(node6);
        node3.setRight(node7);

        return node1;
    }
}

@Data
class ThreadedTree{
//    当前树的根节点
    private ThreadedTreeNode root;
//    当前树的上一个节点
    private ThreadedTreeNode pre;

    public ThreadedTree(ThreadedTreeNode root) {
        this.root = root;
    }

    /**
     * 二叉树的线索化(前序)
     * @param node  需要线索化的当前节点
     */
    public void preThreadedNodes(ThreadedTreeNode node){
        if (node == null) {
            return;
        }
//        1.线索化当前节点
//          1.1线索化前驱节点
        if (node.getLeft() == null) {
            node.setLeft(pre);
            node.setLeftType(1);
        }
//          1.2线索化后继节点
        if (pre != null && pre.getRight() == null) {
            pre.setRight(node);
            pre.setRightType(1);
        }
        pre = node;
//        2.线索化左节点
        if (node.getLeftType() == 0) {
            preThreadedNodes(node.getLeft());
        }
//        3.线索化右节点
        if (node.getRightType() == 0) {
            preThreadedNodes(node.getRight());
        }
    }

    /**
     * 二叉树的线索化(中叙)
     * @param node 需要线索化的当前节点
     */
    public void midThreadedNodes(ThreadedTreeNode node){
        if (node == null) {
            return;
        }
//        1.线索化左节点
        midThreadedNodes(node.getLeft());
//        2.线索化当前节点
//          2.1处理前驱节点
        if (node.getLeft() == null) {
            node.setLeft(pre);
            node.setLeftType(1);
        }
//          2.2处理后继节点
        if (pre != null && pre.getRight() == null) {
            pre.setRight(node);
            pre.setRightType(1);
        }
        pre = node;
//        3.线索化右节点
        midThreadedNodes(node.getRight());
    }

    /**
     * 二叉树的线索化(后续)
     * @param node  需要线索化的当前节点
     */
    public void postThreadedNodes(ThreadedTreeNode node){
        if (node == null) {
            return;
        }
//        1.线索化左节点
        if (node.getLeftType() == 0) {
            postThreadedNodes(node.getLeft());
        }
//        2.线索化右节点
        if (node.getRightType() == 0) {
            postThreadedNodes(node.getRight());
        }
//        3.线索化当前节点
//          3.1处理前驱节点
        if (node.getLeft() == null) {
            node.setLeft(pre);
            node.setLeftType(1);
        }
//          3.2处理后继节点
        if (pre != null && pre.getRight() == null) {
            pre.setRight(node);
            pre.setRightType(1);
        }
        pre = node;
    }


    /**
     * 前序遍历(线索化二叉树)
     */
    public void listPreThreadedNodes(){
//        定义一个临时变量,用于存储遍历的当前节点
        ThreadedTreeNode node = root;
        while(node != null){
            System.out.println(node.getVal());
            while(node.getLeftType() == 0){
                node = node.getLeft();
                System.out.println(node.getVal());
            }
            node = node.getRight();
        }
    }

    /**
     * 中叙遍历(线索化二叉树)
     */
    public void listMidThreadedNodes(){
//        定义一个临时变量,用于存储遍历的当前节点
        ThreadedTreeNode node = root;
        while(node != null){
//            循环找到leftType==1的节点
            while(node.getLeftType() == 0){
                node = node.getLeft();
            }
//            打印当前节点
            System.out.println(node.getVal());
//            如果当前节点的右节点是后继节点,则继续向下遍历
            while(node.getRightType() == 1){
                node = node.getRight();
                System.out.println(node.getVal());
            }
//            如果当前节点的右节点不是后继节点,则替换当前节点
            node = node.getRight();
        }
    }

    /**
     * 后序遍历(和普通遍历一样,这样写很傻逼,但是就是简单,[苦涩])
     * @param node
     */
    public void listPostThreadedNodes(ThreadedTreeNode node){
        if (node.getLeft () != null && node.getLeftType() == 0) {
            listPostThreadedNodes(node.getLeft());
        }
        if (node.getRight() != null && node.getRightType() == 0) {
            listPostThreadedNodes(node.getRight());
        }
        System.out.println(node.getVal());
    }


}

@Data
class ThreadedTreeNode {
    private Integer val;
    private ThreadedTreeNode left;
    private ThreadedTreeNode right;
//    type:0(未线索化)      type:1(线索化)
    private Integer leftType = 0;
    private Integer rightType = 0;

    public ThreadedTreeNode(Integer val) {
        this.val = val;
    }

    @Override
    public String toString() {
        return "TreeNode{" +
                "val=" + val +
                '}';
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

难过的风景

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值