【我是一棵树】二叉树详解(二)

二叉树的存储结构

顺序存储就是用一组数组来存储二叉树中节点,并且节点的存储位置,也就是数组的下标要能体现节点之间的逻辑关系。

考虑一种极端情况,一棵深度为k的右斜数,它只有k个节点,却需要分配2^k-1个存储单元,这显然是对空间的浪费,所以顺序的存储结构只适用于完全二叉树。

二叉链表既然顺序存储结构实用性不强,我们就要考虑练市存储结构。二叉树每个节点最多有两个孩子,所以它设计一个数据域和两个指针域是比较自然的想法。我们称这样的链表叫做二叉链表。

二叉树遍历原理

二叉树的遍历是从根节点出发,按照某种次序依次访问二叉树中所有节点,使得每个节点的被访问一次且仅被访问一次。

二叉树的遍历方法

前序遍历:根-->左-->右

中序遍历:左-->根-->右

后序遍历:左-->右-->根

二叉树遍历的JAVA实现

public class BinaryTree {
    public static void main(String[] args) {
        BinaryTree binaryTree = new BinaryTree();
        System.out.print("前序遍历:");
        binaryTree.preOrderTraverse(binaryTree.init());
        System.out.println();
        System.out.print("中序遍历:");
        binaryTree.InOrderTraverse(binaryTree.init());
        System.out.println();
        System.out.print("后序遍历:");
        binaryTree.PostOrderTraverse(binaryTree.init());
    }

    private BinaryTreeNode init() {
        BinaryTreeNode root = new BinaryTreeNode("a");
        BinaryTreeNode nodeB = new BinaryTreeNode("b");
        BinaryTreeNode nodeC = new BinaryTreeNode("c");
        root.setLchild(nodeB);
        root.setRchild(nodeC);
        BinaryTreeNode nodeD = new BinaryTreeNode("d");
        BinaryTreeNode nodeE = new BinaryTreeNode("e");
        nodeB.setLchild(nodeD);
        nodeB.setRchild(nodeE);
        BinaryTreeNode nodeH = new BinaryTreeNode("h");
        nodeD.setLchild(nodeH);
        BinaryTreeNode nodeK = new BinaryTreeNode("k");
        nodeH.setRchild(nodeK);
        BinaryTreeNode nodeF = new BinaryTreeNode("f");
        BinaryTreeNode nodeG = new BinaryTreeNode("g");
        nodeC.setLchild(nodeF);
        nodeC.setRchild(nodeG);
        BinaryTreeNode nodeI = new BinaryTreeNode("i");
        nodeF.setLchild(nodeI);
        BinaryTreeNode nodeJ = new BinaryTreeNode("j");
        nodeG.setRchild(nodeJ);
        return root;
    }

    /**
     * 前序遍历
     *
     * @param binaryTreeNode
     */
    private void preOrderTraverse(BinaryTreeNode binaryTreeNode) {
        if (binaryTreeNode == null) {
            return;
        }
        System.out.print(binaryTreeNode.getData() + " ");
        preOrderTraverse(binaryTreeNode.getLchild());
        preOrderTraverse(binaryTreeNode.getRchild());
    }

    /**
     * 中序遍历
     *
     * @param binaryTreeNode
     */
    private void InOrderTraverse(BinaryTreeNode binaryTreeNode) {
        if (binaryTreeNode == null) {
            return;
        }
        InOrderTraverse(binaryTreeNode.getLchild());
        System.out.print(binaryTreeNode.getData() + " ");
        InOrderTraverse(binaryTreeNode.getRchild());
    }

    /**
     * 后序遍历
     *
     * @param binaryTreeNode
     */
    private void PostOrderTraverse(BinaryTreeNode binaryTreeNode) {
        if (binaryTreeNode == null) {
            return;
        }
        PostOrderTraverse(binaryTreeNode.getLchild());
        PostOrderTraverse(binaryTreeNode.getRchild());
        System.out.print(binaryTreeNode.getData() + " ");
    }

    class BinaryTreeNode {
        private String data;
        private BinaryTreeNode lchild;
        private BinaryTreeNode rchild;

        public BinaryTreeNode() {
        }

        public BinaryTreeNode(String data) {
            this.data = data;
        }

        public String getData() {
            return data;
        }

        public void setData(String data) {
            this.data = data;
        }

        public BinaryTreeNode getLchild() {
            return lchild;
        }

        public void setLchild(BinaryTreeNode lchild) {
            this.lchild = lchild;
        }

        public BinaryTreeNode getRchild() {
            return rchild;
        }

        public void setRchild(BinaryTreeNode rchild) {
            this.rchild = rchild;
        }
    }
}

线索二叉树

指向前驱和后继的指针为线索,加上线索的二叉链表称为线索链表。相应的二叉树就称为线索二叉树。

二叉树以某种次序遍历使其变为线索二叉树的过程称作是线索化。

线索化的实质

就是将二叉链表中的空指针改为指向前驱和后继的线索。由于前驱和后继的信息只有在遍历该二叉树时才能得到。所以线索化的过程就是在遍历的过程中修改空指针。

发布了83 篇原创文章 · 获赞 58 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/qixinbruce/article/details/104066547
今日推荐