day6 顺序储存二叉树 和 线索化二叉树及遍历

顺序储存二叉树

public class welltree {
    public static void main(String[] args) {
        int []x = {1,2,3,4,5,6,7};
        tree1 t = new tree1(x);
//        t.preOrder(0);//前序遍历
//        t.fixOrder(0);//中序遍历
        t.lastOrder(0);//后序遍历
    }
}
//顺序存储二叉树
class tree1{
    private int []arr;
    public tree1(int []x){
        arr = x;
    }
    //通过传入的索引在树中的位置开始前序遍历
    public void preOrder(int index){
        //查看数组内是否为空 和数组是否被使用
        if (arr==null&&arr.length==0){
            System.out.println("无数据");
        }else{
            //输出当前节点
            System.out.println(arr[index]);
            //防止越界 判断当前节点有没有左子节点
            if (index*2+1 < arr.length){
                //如果有以当前节点的左子节点为根节点进行前序遍历
                preOrder(index*2+1);
            }
            //同上 这个是右子节点
            if (index*2+2 < arr.length){
                preOrder(index*2+2);
            }
        }
    }
    //通过传入的索引在树中的位置开始中序遍历
    public void fixOrder(int index){
        //查看数组内是否为空 和数组是否被使用
        if (arr==null&&arr.length==0){
            System.out.println("无数据");
        }else{
            //防止越界 判断当前节点有没有左子节点
            if (index*2+1 < arr.length){
                //如果有以当前节点的左子节点为根节点进行中序遍历
                fixOrder(index*2+1);
            }
            //输出当前节点
            System.out.println(arr[index]);
            //同上 这个是右子节点
            if (index*2+2 < arr.length){
                fixOrder(index*2+2);
            }
        }
    }
    //通过传入的索引在树中的位置开始后序遍历
    public void lastOrder(int index){
        //查看数组内是否为空 和数组是否被使用
        if (arr==null&&arr.length==0){
            System.out.println("无数据");
        }else{
            //防止越界 判断当前节点有没有左子节点
            if (index*2+1 < arr.length){
                //如果有以当前节点的左子节点为根节点进行后序遍历
                lastOrder(index*2+1);
            }
            //同上 这个是右子节点
            if (index*2+2 < arr.length){
                lastOrder(index*2+2);
            }
            //输出当前节点
            System.out.println(arr[index]);
        }
    }

}

线索化二叉树

public class treeTest {
    public static void main(String[] args) {
        //创建节点
        node node1 = new node(1,"阿狸");
        node node2 = new node(2,"剑圣");
        node node3 = new node(3,"亚索");
        node node4 = new node(4,"盖伦");
        node node5 = new node(5,"卡特");
        node node6 = new node(6,"螳螂");
        //建立树的关系
        tree tree = new tree();
        //设置根节点
        tree.setnode(node1);
        //设置节点的左节点和右节点
        node1.setLeft(node2);
        node1.setRight(node3);
        node2.setLeft(node4);
        node2.setRight(node5);
        node3.setLeft(node6);
        preOrderTree preOrderTree = new preOrderTree();
        preOrderTree.setRoot(node1);

//        //前序遍历  先当前节点 然后当前节点的左节点 然后右节点
//        System.out.println("前序遍历");
//        tree.preOrder();
//        //中序遍历   先当前节点的左节点 再当前节点 然后右节点
//        System.out.println("中序遍历");
//        tree.fixOrder();
//        //后序遍历   先当前节点的左节点 然后右节点 再当前节点
//        System.out.println("后序遍历");
//        tree.lastOrder();
//        System.out.println("前序查找");
//        node cz1 =  tree.preOrderSearch(4);
//        System.out.println(cz1);
//        System.out.println("中序查找");
//        node cz2 =  tree.fixOrderSearch(4);
//        System.out.println(cz2);
//        System.out.println("后序查找");
//        node cz3 =  tree.lastOrderSearch(4);
//        System.out.println(cz3);
//        System.out.println("删除节点前 - 前序遍历");
//        tree.preOrder();
//        //删除节点
//        tree.delete(3);
//        System.out.println("删除节点后 - 前序遍历");
//        tree.preOrder();
        preOrderTree.qxtree();//线索化
        System.out.println(node5.getLeft());
        System.out.println(node5.getRight());
        System.out.println("遍历前序线索化树");
        preOrderTree.qxTreeb();
    }
}
//创建前序线索二叉树
class preOrderTree{
    private node pre = null;//在线索化的时候用来储存前驱节点
    private node root;//根节点
    //设置根节点
    public void setRoot(node root){
        this.root = root;
    }
    public preOrderTree(){
        qxtree(root);
    }
    //重载 这样调用方法时就不需要自己传跟根节点了
    public void qxtree(){
        qxtree(this.root);
    }
    //前序线索化二叉树
    public void qxtree(node root){
        //防止空节点
        if (root==null){
            return;
        }
//        System.out.println(root);
//        if (root.getLeft()!=null){

//        }
//        System.out.println(root);
        //因为是前序 先线索化当前节点
//        System.out.println("root: "+root);
        System.out.println("pre: "+pre);
        if (root.getLeft()==null){
            root.setLeft(pre);
//            System.out.println(root);
            root.setLeftType(true);
        }

        if (pre!=null&&pre.getRight()==null){
            pre.setRight(root);
//            System.out.println(pre+"  "+pre.getRight());
            pre.setRightType(true);
        }
        pre = root;
//        if (root.getRight()!=null){
        //切记记得判断当前节点是不是被设置过前驱或者后继   不然会死循环!!!
        if (!root.isLeftType()) {
            qxtree(root.getLeft());
        }
        if (!root.isRightType()) {
            qxtree(root.getRight());
        }
//        }
//        System.out.println(pre);
//        System.out.println(root);

    }
    //前序线索化树的遍历
    public void qxTreeb(){
        //节点不能为空
        if (root==null){
            return;
        }
        //辅助变量 用来帮助遍历
        node sign = root;
        //当辅助变量的值不为null 就一直循环
        while (sign!=null){
            //当辅助变量当前值的左子节点不为空 并且他的左子节点不是代表他的前驱的时候循环
           while (sign.getLeft()!=null&& !sign.isLeftType()){
               System.out.println(sign);
               sign = sign.getLeft();
           }
           //输出当前sign代表的节点的值
            System.out.println(sign);
           //如果当前节点的左子节点代表的是他的前驱 那么跳过这个节点
           if (sign.isLeftType()){
               sign = sign.getRight();
           }
           //当sign的值不为null并且sign的右边代表的是他的后继的时候循环
           while (sign!=null&&sign.isRightType()){
               System.out.println(sign);
               sign = sign.getRight();
           }
        }
    }
}
//创建树
class tree{
    //创建一个根节点
    private node nodex;
    //接受根节点
    public void setnode(node node){
        this.nodex = node;
    }
    //前序遍历
    public void preOrder(){
        if (this.nodex !=null){
            this.nodex.preOrder();
        }else{
            System.out.println("树空!");
        }
    }
    //中序遍历
    public void fixOrder(){
        if (this.nodex !=null){
            this.nodex.fixOrder();
        }else{
            System.out.println("树空!");
        }
    }
    //后序遍历
    public void lastOrder(){
        if (this.nodex !=null){
            this.nodex.lastOrder();
        }else{
            System.out.println("树空!");
        }
    }
    //前序查找
    public node preOrderSearch(int i){
        //如果根节点不为空
        if (nodex!=null){
            //返回 以当前根节点为根节点的前序查找方法的返回值
            return nodex.preOrderSearch(i);
        }else{
            //如果根节点都为null 那么返回null
            return null;
        }
    }
    //中序查找
    public node fixOrderSearch(int i){
        if (nodex!=null){
            return nodex.fixOrderSearch(i);
        }else{
            return null;
        }
    }
    //后序查找
    public node lastOrderSearch(int i){
        if (nodex!=null){
            return nodex.lastOrderSearch(i);
        }else{
            return null;
        }
    }
    //删除节点
    public void delete(int i){

        if (nodex!=null){
            if (nodex.getId()==i){
                nodex = null;
            }else{
                nodex.delete(i);
            }
        }else{
            System.out.println("树空!");
        }
    }
}
//创建数的节点
class node{
    private int id;//编号
    private String name;//名称
    private node left;//左子节点
    private node right;//右子节点
    private boolean leftType = false;//用来编辑当前节点的左指针域链接的是 左子节点 还是他的前驱
    private boolean rightType = false;//用来编辑当前节点的右指针域链接的是 右子节点 还是他的后继
    //构造节点

    public void setRightType(boolean rightType) {
        this.rightType = rightType;
    }

    public boolean isRightType() {
        return rightType;
    }

    public boolean isLeftType() {
        return leftType;
    }

    public void setLeftType(boolean leftType) {
        this.leftType = leftType;
    }

    public node(int id, String name){
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    //设置左子节点
    public void setLeft(node left) {
        this.left = left;
    }
    //设置右子节点
    public void setRight(node right) {
        this.right = right;
    }
    //获取左子节点
    public node getLeft() {
        return left;
    }
    //获取右子节点
    public node getRight() {
        return right;
    }
    //重写tostring方法

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

    //前序遍历二叉树
    public void preOrder(){
        //根节点
        //this就是你是通过那个节点调用的这个方法那么this就是那个节点
            System.out.println(this);
        //如果左子节点不为空
        if (this.left!=null){
            //那么继续以当前左子节点为根节点的前序遍历
            this.left.preOrder();
        }
        //如果右子节点不为空
        if (this.right!=null){
            //同上
            this.right.preOrder();
        }
    }

    //中序遍历二叉树
    public void fixOrder(){

        //如果左子节点不为空
        if (this.left!=null){
            //那么继续以当前左子节点为根节点的前序遍历
            this.left.fixOrder();
        }
        //根节点
        //this就是你是通过那个节点调用的这个方法那么this就是那个节点
        System.out.println(this);
        //如果右子节点不为空
        if (this.right!=null){
            //同上
            this.right.fixOrder();
        }
    }
    //后序遍历二叉树
    public void lastOrder(){

        //如果左子节点不为空
        if (this.left!=null){
            //那么继续以当前左子节点为根节点的前序遍历
            this.left.lastOrder();
        }
        //如果右子节点不为空
        if (this.right!=null){
            //同上
            this.right.lastOrder();
        }
        //根节点
        //this就是你是通过那个节点调用的这个方法那么this就是那个节点
        System.out.println(this);

    }
    //前序查找
    public node preOrderSearch(int i){
        //标记  用来判断是否找到了目标
        node sign = null;
        //如果当前节点的id=目标id
        //这个消息输出了几次 就代表通过几个节点找到的 注意位置要在判断this.id的地方的前面 只有这个是在判断是否符合条件
        System.out.println("前序查找次数验证");
        if (this.id==i){
            //那么返回这个节点
            return this;
        }
        //如果当前节点的左子节点不为空
        if (this.left!=null){
            //那么sign标记就 = 以当前节点的左子节点为跟再前序查找目标的返回值
            sign = this.left.preOrderSearch(i);
        }
        //如果标记被改变了 不为null了 那么返回他自己结束方法
        if (sign!=null){
            return sign;
        }
        if (this.right!=null){
            sign = this.right.preOrderSearch(i);
        }
        //到了这里无论是否找到都返回sign的值
        return sign;
    }
    //中序查找
    public node fixOrderSearch(int i){
        node sign = null;
        if (this.left!=null){
            sign = this.left.fixOrderSearch(i);
        }
        if (sign!=null){
            return sign;
        }
        System.out.println("中序查找次数验证");
        if (this.id==i){
            return this;
        }
        if (this.right!=null){
            sign = this.right.fixOrderSearch(i);
        }
        return sign;
    }
    //后序查找
    public node lastOrderSearch(int i){
        node sign = null;
        if (this.left!=null){
            sign = this.left.lastOrderSearch(i);
        }
        if (sign!=null){
            return sign;
        }
        if (this.right!=null){
            sign = this.right.lastOrderSearch(i);
        }
        if (sign!=null){
            return sign;
        }
        System.out.println("后序查找次数验证");
        if (this.id==i){
            return this;
        }
        return sign;
    }
    //通过id来删除对应的节点
    public void delete(int i){
        //因为删除节点的特殊性 想删除一个节点必须通过他的上一个节点所以这里判断的都是.next
        if (this.left!=null&&this.left.id==i){
            this.left = null;
            return;
        }
        if (this.right!=null&&this.right.id==i){
            this.right = null;
            return;
        }
        //如果当前节点的左右子节点都不是目标节点 那么就分别以当前左子节点为根节点继续删 和以右..
        if (this.left!=null){
            this.left.delete(i);
        }
        if (this.right!=null){
            this.right.delete(i);
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值