首页 > 编程语言 >数据结构与算法__03--二叉树前序线索化与前序线索化遍历(Java语言版)

数据结构与算法__03--二叉树前序线索化与前序线索化遍历(Java语言版)

时间:2022-12-08 13:32:07浏览次数:56  
标签:node no 前序 HeroNode public 二叉树 null root 线索

(目录)

1 前序线索化与前序线索化遍历

1.1 前序线索化二叉树


public void threadedPreNode(HeroNode node) {
    if (node == null) {
        return;
    }
    //线索化当前节点
    if (node.getLeft() == null) {
        node.setLeft(pre);
        node.setLeftType(1);
    }
    if (pre != null && pre.getRight() == null) {
        pre.setRight(node);
        pre.setRightType(1);
    }
    pre = node;
    //线索化左子树
    if (node.getLeftType() != 1) {
        threadedPreNode(node.getLeft());
    }
    //线索化右子树
    if (node.getRightType() != 1) {
        threadedPreNode(node.getRight());
    }
 
}

1.2 前序线索化遍历

public void threadedPreList() {
    //定义一个变量,存储当前遍历的结点,从root开始
    HeroNode node = root;
    while (node != null) {
        //打印当前这个结点
        System.out.println(node);
        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();
 
    }
}

2 完整代码

package edu.seu.demo10tree.demothreadedbinarytree;
 
public class Demo01ThreadedBinaryTree {
    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);
 
        //测试中序线索化  8, 3, 10, 1, 14, 6
        ThreadedBinaryTree threadedBinaryTree = new ThreadedBinaryTree();
        threadedBinaryTree.setRoot(root);
 
//        threadedBinaryTree.threadedNode();
//        中序  8, 3, 10, 1, 14, 6
//        HeroNode leftNode = node5.getLeft();
//        HeroNode rightNode = node5.getRight();
//        System.out.println("10号结点的前驱结点是="  + leftNode); //3
//        System.out.println("10号结点的后继结点是="  + rightNode); //1
 
//        System.out.println("使用线索化的方式遍历 线索化二叉树");
//        threadedBinaryTree.threadedList();
 
//        前序 1,3,8,10,6,14
        threadedBinaryTree.threadedPreNode(root);
        HeroNode leftNode = node5.getLeft();
        HeroNode rightNode = node5.getRight();
        System.out.println("10号结点的前驱结点是=" + leftNode);
        System.out.println("10号结点的后继结点是=" + rightNode);
 
        System.out.println("使用线索化的方式遍历 线索化二叉树");
        threadedBinaryTree.threadedPreList();
 
    }
}
 
class HeroNode {
    private int no;//英雄编号
    private String name;//姓名
    private HeroNode left;//左子节点
    private HeroNode right;//右子节点
    private int rightType;//表示右子节点:指针:0,后继:1
    private int leftType;//表示左子节点:指针:0  前驱:1
 
    public int getRightType() {
        return rightType;
    }
 
    public void setRightType(int rightType) {
        this.rightType = rightType;
    }
 
    public int getLeftType() {
        return leftType;
    }
 
    public void setLeftType(int leftType) {
        this.leftType = leftType;
    }
//构造方法
 
    public HeroNode(int no, String name) {
        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;
    }
 
    //打印输出
 
    @Override
    public String toString() {
        return "HeroNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                '}';
    }
 
    //前序遍历
    public void preOrder() {
        System.out.println(this);//1.输出父节点
        if (this.getLeft() != null) {//2.向左遍历
            this.getLeft().preOrder();
        }
        if (this.getRight() != null) {//3.向右遍历
            this.getRight().preOrder();
        }
    }
 
    //中序遍历
    public void infixOrder() {
        if (this.getLeft() != null) {
            this.getLeft().infixOrder();
        }
        System.out.println(this);
        if (this.getRight() != null) {//3.向右遍历
            this.getRight().infixOrder();
        }
    }
 
    //后序遍历
    public void postOrder() {
        if (this.getLeft() != null) {
            this.getLeft().postOrder();
        }
        if (this.getRight() != null) {//3.向右遍历
            this.getRight().postOrder();
        }
        System.out.println(this);
    }
 
    //前序遍历查找
    public HeroNode preOrderSearch(int no) {
        System.out.println("前序查找比较次数");
        if (this.getNo() == no) {
            return this;
        }
        HeroNode resHero = null;
        if (this.left != null) {
            resHero = this.left.preOrderSearch(no);
        }
        if (resHero != null) {
            return resHero;
        }
        if (this.right != null) {
            resHero = this.right.preOrderSearch(no);
        }
        return resHero;
    }
 
    //中序遍历查找
    public HeroNode infixOrderSearch(int no) {
        HeroNode resHero = null;
        if (this.left != null) {
            resHero = this.left.infixOrderSearch(no);
        }
        if (resHero != null) {
            return resHero;
        }
        System.out.println("中序查找比较次数");
        if (this.getNo() == no) {
            return this;
        }
        if (this.right != null) {
            resHero = this.right.infixOrderSearch(no);
        }
        return resHero;
    }
 
    //后序遍历查找
    public HeroNode postOrderSearch(int no) {
        HeroNode resHero = null;
        if (this.left != null) {
            resHero = this.left.postOrderSearch(no);
        }
        if (resHero != null) {
            return resHero;
        }
 
        if (this.right != null) {
            resHero = this.right.postOrderSearch(no);
        }
        if (resHero != null) {
            return resHero;
        }
        System.out.println("后序查找比较次数");
        if (this.getNo() == no) {
            return this;
        }
        return resHero;
    }
 
    //删除节点
    public void delHeroNode(int no) {
        if (this.left != null && this.left.getNo() == no) {
            this.left = null;
            return;
        }
        if (this.right != null && this.right.getNo() == no) {
            this.right = null;
            return;
        }
        if (this.left != null) {
            this.left.delHeroNode(no);
        }
        if (this.right != null) {
            this.right.delHeroNode(no);
        }
    }
 
}
 
class ThreadedBinaryTree {
    private HeroNode root;//根节点
    private HeroNode pre = null;
 
    public ThreadedBinaryTree() {
    }
 
    public void threadedNode() {
        threadedNode(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 threadedNode(HeroNode node) {
        if (node == null) {
            return;
        }
        //线索化左子树
        threadedNode(node.getLeft());
        //线索化当前节点
        if (node.getLeft() == null) {
            node.setLeft(pre);
            node.setLeftType(1);
        }
        if (pre != null && pre.getRight() == null) {
            pre.setRight(node);
            pre.setRightType(1);
        }
        pre = node;
        //线索化右子树
        threadedNode(node.getRight());
    }
    //前序线索化二叉树
    public void threadedPreNode(HeroNode node) {
        if (node == null) {
            return;
        }
        //线索化当前节点
        if (node.getLeft() == null) {
            node.setLeft(pre);
            node.setLeftType(1);
        }
        if (pre != null && pre.getRight() == null) {
            pre.setRight(node);
            pre.setRightType(1);
        }
        pre = node;
        //线索化左子树
        if (node.getLeftType() != 1) {
            threadedPreNode(node.getLeft());
        }
        //线索化右子树
        if (node.getRightType() != 1) {
            threadedPreNode(node.getRight());
        }
 
    }
 
    //前序线索化遍历
    public void threadedPreList() {
        //定义一个变量,存储当前遍历的结点,从root开始
        HeroNode node = root;
        while (node != null) {
            //打印当前这个结点
            System.out.println(node);
            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 HeroNode getRoot() {
        return root;
    }
 
    public void setRoot(HeroNode root) {
        this.root = root;
    }
 
 
    //前序遍历
    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 this.root.postOrderSearch(no);
        } else {
            return null;
        }
    }
 
    //删除节点
    public void delHeroNode(int no) {
        if (root != null) {
            if (root.getNo() == no) {
                root = null;
            } else {
                root.delHeroNode(no);
            }
        } else {
            System.out.println("二叉树为空");
        }
    }
}

标签:node,no,前序,HeroNode,public,二叉树,null,root,线索
From: https://blog.51cto.com/husheng/5921039

相关文章

  • 【代码随想录】第8章 二叉树
    第8章二叉树1.二叉树理论基础二叉树种类(1)满二叉树(2)完全二叉树(3)二叉搜索树或称二叉查找树中序遍历是递增序列(4)平衡二叉搜索树二叉树的存储方式可以链式存储,也可以顺序存......
  • 二叉树的最小深度问题
    二叉树的最小深度问题作者:Grey原文地址:博客园:二叉树的最小深度问题CSDN:二叉树的最小深度问题题目描述给定一个二叉树,找出其最小深度。最小深度是从根节点到最近叶......
  • Java中二叉树的遍历、查找
    1、准备节点/***二叉树的节点*@authorlurenjia*@date2022/12/7-12:07*/publicclassNode{Objectvalue;NodeleftChild;NoderightChild......
  • 3、二叉树
    树(Tree)是n个结点的有限集合。度:拥有子结点的数量为结点的度,树中最大的度为树的度。结点(节点):根结点、内部结点、叶子结点有序树:左分支和右分支......
  • 代码随想录算法训练营Day16| 104. 二叉树的最大深度、559.n叉树的最大深度、111. 二叉
    代码随想录算法训练营Day16|104.二叉树的最大深度、559.n叉树的最大深度、111.二叉树的最小深度、222.完全二叉树的节点个数104.二叉树的最大深度104.二叉树的最大......
  • 判断是否是完全二叉树
     对于一棵二叉树,判断是否是一棵完全二叉树。typedefstructNode{intkey;Node*lChild;Node*rChild;}*PNode;boolis(PNode&p){boolflag=false;queue<PN......
  • 每日算法之二叉树中和为某一值的路径(二)
    JZ34二叉树中和为某一值的路径(二)描述输入一颗二叉树的根节点root和一个整数expectNumber,找出二叉树中结点值的和为expectNumber的所有路径。1.该题路径定义为从树的......
  • 二叉树入门到进阶(下一篇讲红黑树)——c语言刷题合集
    目录二叉树概念二叉树的遍历方式DFS(前序中序后序遍历)144.二叉树的前序遍历递归解法迭代解法94.二叉树的中序遍历145.二叉树的后序遍历层序遍历--队列的作用102.二叉......
  • ChatGPT 编写的 Rust 二叉树
    //定义二叉树节点structNode{  //节点值  value:i32,  //左子树  left:Option<Box<Node>>,  //右子树  right:Option<Box<Node......
  • 根据前序和中序遍历重建二叉树
    关于最近最近在看算法相关的,接下来想记录一下自己学习的、个人认为比较值得记录的算法。这篇博客主要是用自己的理解复述了根据中序、前序遍历重建二叉树这个博客的内容,......