数据结构-线索二叉树(线索化和遍历线索二叉树)

文章目录

思路

声明

线索二叉树结点中含有五个变量,分别是该结点存储的值,该结点指向的左右结点,该结点左右两边的索引值,当左右索引值为 false 就表示左右指向正常的孩子结点,若为 true 表示左右指向前驱或者后继结点

为什么要线索化二叉树呢?

我们知道对于一个满二叉树来讲,其叶子结点为2^(n-1)个,这些叶子空指针域有2^n个,这个 n 是树的深度,我们可以利用这些空指针域来存放一些有意义的信息

为什么我没写后序遍历线索二叉树?

后序的话有些麻烦,建议把后序的左右根通过倒序的根右左来遍历,然后再倒序即可,这个根右左的写法和先序就很类似了

Java 实现

// 结点
class Node {
    int data;
    // 左索引
    boolean leftType;
    Node left = null;
    // 右索引
    boolean rightType;
    Node right = null;
}

// 线索二叉树
public class ThreadedBinaryTree {
    // 根结点
    private Node root;
    // 前驱结点
    private Node pre;
    // 输入的数组
    private int[] arr_in;
    // 输出的数组
    private int[] arr_out;
    // 记录数组下标
    private static int index;
    
    // 初始化
    public ThreadedBinaryTree(int[] arr) {
        root = new Node();
        pre = null;
        this.arr_in = arr;
        arr_out = new int[arr.length];
        index = 0;
    }
    
    // 先序线索化二叉树
    public Node preThreading(Node r) {
        if (r) {
            if (r.left == null) {                
                r.leftType = true;
                r.left = pre;
            }
            else
                r.leftType = false;
            if (pre.right == null) {
                pre.rightType = true;
                pre.right = r;
            }
            else
                pre.rightType = false;
            pre = r;
            preThreading(r.left);
            preThreading(r.right);
        }
        return r;
    }
    
    // 中序线索化二叉树
    public Node inThreading(Node r) {
        if (r) {
            preThreading(r.left);
            if (r.left == null) {                
                r.leftType = true;
                r.left = pre;
            }
            else
                r.leftType = false;
            if (pre.right == null) {
                pre.rightType = true;
                pre.right = r;
            }
            else
                pre.rightType = false;
            pre = r;
            preThreading(r.right);
        }
        return r;
    }
    
    // 后序线索化二叉树
    public void postThreading(Node r) {
        if (r) {
            preThreading(r.left);
            preThreading(r.right);
            if (r.left == null) {                
                r.leftType = true;
                r.left = pre;
            }
            else
                r.leftType = false;
            if (pre.right == null) {
                pre.rightType = true;
                pre.right = r;
            }
            else
                pre.rightType = false;
            pre = r;
        }
        return r;
    }
    
    // 先序遍历线索二叉树
    public void preTraverse(Node r) {
        Node n = r;
        while (n) {
            System.out.println(n.data);
            while (!n.leftType) {
                n = n.left;
                System.out.println(n.data);
            }
            n = n.right;
        }
    }
    
    // 中序遍历线索二叉树
    public void inTraverse(Node r) {
        Node n = r;
        while (n) {
            while (!n.leftType)
                n = n.left;
            System.out.println(n.data);
            while (n.rightType) {
                n = n.right;
                System.out.println(n.data);
            }
            n = n.right;
        }
    }
}
发布了197 篇原创文章 · 获赞 62 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/abcnull/article/details/104565874