[数据结构] 线索化二叉树

package com.guigu.tree.thread;

/**
 * @author: guorui fu
 * @versiion: 1.0
 * 线索化二叉树
 */
public class TreadBinaryTreeDemo {
    public static void main(String[] args) {
        //测试中序线索二叉树功能
        HeroNode root = new HeroNode(1, "宋江");
        HeroNode node2 = new HeroNode(3, "吴用");
        HeroNode node3 = new HeroNode(6, "卢俊义");
        HeroNode node4 = new HeroNode(8, "林冲");
        HeroNode node5 = new HeroNode(10, "关胜");
        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节点
//        System.out.println("10号前驱节点" + node5.getLeft());
//        System.out.println("10号后继节点" + node5.getRight());

        //遍历线索化二叉树
//        System.out.println("遍历线索化二叉树");
//        threadedBinaryTree.threadedList();//8 3 10 1 14 6
        System.out.println("前序遍历线索化二叉树");
        threadedBinaryTree.threadedNodes1();
        threadedBinaryTree.threadedList1(root);

//        System.out.println("遍历线索化二叉树");
//        threadedBinaryTree.threadedList2();

    }
}

//创建二叉树
class ThreadedBinaryTree{
    private HeroNode root;
    //为实现线索化 创建指向前驱节点的指针
    //递归线序化时 保留前一个节点
    private HeroNode pre = null;

    public void setRoot(HeroNode root) {
        this.root = root;
    }

    //重载threadedNodes方法
    public void threadedNodes(){
        this.threadedNodes(root);
    }
    //重载threadedNodes1方法
    public void threadedNodes1(){
        this.threadedNodes(root);
    }

    //遍历中序线索化二叉树
    public void threadedList(){
        //定义一个变量,存储当前遍历的节点,从root开始
        HeroNode node = root;
        while (node != null){
            //循环找到leftType == 1的节点,第一个是8节点
            //随着遍历会发生变化,leftType == 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();
        }
    }

    //遍历前序线索化二叉树
    public void threadedList1(HeroNode heroNode){
        //定义一个变量,存储当前遍历的节点,从root开始
        HeroNode node = heroNode;
        if (node == null) {
            return;
        }

        if (node.getLeftType() == 1 || node.getRightType() == 1){
            System.out.println(node);
        }
        System.out.println(node);
        threadedList1(node.getLeft());
        threadedList1(node.getRight());
    }

//    //遍历后序线索化二叉树
//    public void threadedList2(){
//        //定义一个变量,存储当前遍历的节点,从root开始
//        HeroNode node = root;
//        while (node != null){
//
//            //循环找到leftType == 1的节点,第一个是8节点
//            //随着遍历会发生变化,leftType == 1节点是线索化后的有效节点
//            while (node.getLeftType() == 0){
//                node = node.getLeft();
//            }
//            //如果当前节点的右指针指向的是后继节点,就一直输出
//            while (node.getRightType() == 1){
//                node = node.getRight();
//                System.out.println(node);
//            }
//            //打印当前节点
//            System.out.println(node);
//            //替换这个遍历的节点
//            node = node.getRight();
//        }
//    }

    //编写中序线索化方法   heroNode为需要线索化的节点
    public void threadedNodes(HeroNode heroNode){
        if (heroNode == null){
            return;
        }

        //1.先线索化左子树
        threadedNodes(heroNode.getLeft());

        //2.线索化当前节点
        if (heroNode.getLeft() == null){
            //当前节点的左指针指向前驱节点
            heroNode.setLeft(pre);
            //修改当前节点左指针类型
            heroNode.setLeftType(1);
        }

        //后继节点
        if (pre != null && pre.getRight() == null && pre.getLeft() != heroNode){
            //让前驱节点的右指针指向当前节点
            pre.setRight(heroNode);
            //修改前去节点的右指针类型
            pre.setRightType(1);
        }
        //每处理以恶节点 让当前节点变成下一个节点的前驱节点
        pre = heroNode;

        //3.线索化右子树
        threadedNodes(heroNode.getRight());

    }

    //编写前序线索化方法   heroNode为需要线索化的节点
    public void threadedNodes1(HeroNode heroNode){
        if (heroNode == null){
            return;
        }
        //2.线索化当前节点
        if (heroNode.getLeft() == null){
            //当前节点的左指针指向前驱节点
            heroNode.setLeft(pre);
            //修改当前节点左指针类型
            heroNode.setLeftType(1);
        }

        //后继节点
        if (pre != null && pre.getRight() == null){
            //让前驱节点的右指针指向当前节点
            pre.setRight(heroNode);
            //修改前去节点的右指针类型
            pre.setRightType(1);
        }
        //每处理以左节点 让当前节点变成下一个节点的前驱节点
        pre = heroNode;

        //1.先线索化左子树
        threadedNodes(heroNode.getLeft());
        //3.线索化右子树
        threadedNodes(heroNode.getRight());
    }

    //前序遍历
    public void preOrder(){
        if (this.root != null){
            this.root.preOrder();
        }else {
            System.out.println("二叉树为null");
        }
    }

    //中序遍历
    public void infixOrder(){
        if (this.root != null){
            this.root.infixOrder();
        }else {
            System.out.println("二叉树为null");
        }
    }
    //后序遍历
    public void postOrder(){
        if (this.root != null){
            this.root.postOrder();
        }else {
            System.out.println("二叉树为null");
        }
    }

    //前序查找
    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;
        }
    }

    //删除节点 直接删除节点与及其左右节点
    public void delNode(int no){
        if (root != null){//root是否为null
            if (root.getNo() == no){//root是否为删除对象
                root = null;
            }else {
                //判断子节点
                root.delNode(no);
            }
        }else {
            System.out.println("无节点可删除");
        }
    }
}

//创建HeroNode
class HeroNode {
    private int no ;
    private String name;
    private HeroNode left;//默认null
    private HeroNode right;//默认null

    //leftType=0 表示指向左子树  =1表示指向前驱节点
    private int leftType;
    //leftType=0 表示指向右子树  =1表示指向后继节点
    private int rightType;

    public HeroNode(int no, String name) {
        this.no = no;
        this.name = name;
    }

    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 int getNo() {
        return no;
    }

    public void setId(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;
    }

    @Override
    public String toString() {
        return "HeroNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                '}';
    }

    //前序遍历
    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);//输出父节点
    }

    //前序遍历查找
    public HeroNode preOrderSearch(int no){//查找编号
        //比较当前节点是不是
        if (this.no == no){
            return this;
        }
        //查看左节点 找到后返回给resNode
        HeroNode resNode = null;
        if (this.left != null){
            resNode = this.left.preOrderSearch(no);
        }
        //中间加return,左子树找到 这时就不用再去执行下面的右子树
        if (resNode != null){
            return resNode;
        }
        if (this.right != null){
            resNode = this.right.preOrderSearch(no);
        }

        return resNode;
    }

    //中序遍历查找
    public HeroNode infixOrderSearch(int no){
        //判断当前左节点是否为null,不为null则递归中序查找
        HeroNode resNode = null;
        if (this.left != null){//向左查找
            resNode = this.left.infixOrderSearch(no);//递归查找
        }
        if (resNode != null){
            return resNode;
        }
        //查找时判断no是否相等
        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;
        }
        if (this.no == no){
            return this;
        }
        return resNode;
    }

    //递归删除节点
    public void delNode(int no){
        if (this.left != null && this.left.no == no){//左子节点是删除对象
            //左子节点的左子节点不为null
            if (this.left.left != null){

                if (this.left.right !=null){
                    this.left.left = this.left.right;
                }
                this.left = this.left.left;
            }
            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);
        }

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值