如何理解Java数据结构二叉树难点

发布时间:2021-10-25 16:24:08 作者:iii
来源:亿速云 阅读:125

这篇文章主要讲解了“如何理解Java数据结构二叉树难点”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何理解Java数据结构二叉树难点”吧!

 什么是线索二叉树

首先我们来了解一下什么是线索二叉树?

定义:一个二叉树通过如下的方法“穿起来”:所有原本为空的右(孩子)指针改为指向该节点在中序序列中的后继,所有原本为空的左(孩子)指针改为指向该节点的中序序列的前驱。

再看一下为什么要有线索二叉树?

顾名思义,线索二叉树,肯定是根据线索查找,查找速度肯定更快。

那线索仅仅是这样吗?当然不,我们都是懒的,能等待解决的问题,为什么会去想新的办法。我们要解决的是:

最后看一下什么线索二叉树的图解

在我们的线索二叉树的书上,基本上都有以下这张图:

如何理解Java数据结构二叉树难点

大家看到上面这张图还是有点懵的叭,我们一起看一下我下面手画的图

怎么去把二叉树线索化

哦!在着之前献给大家提一下,二叉树的遍历方式,有这样的几种

本博文主要讨论的是中序遍历
它的中序遍历结果就是ABCDE F GHI

如何理解Java数据结构二叉树难点

它的中序线索二叉树遍历如下

先画线索二叉树

如何理解Java数据结构二叉树难点

虚线箭头为线索指针,对于所有左指针指向空的节点:将该节点的左指针指向该节点在中序遍历中的上一节点;对于所有右指针指向空的节点,将该节点的右指针指向该节点在中序遍历中的下一结点。最后一个末尾结点除外。
中序图解线索二叉树

如何理解Java数据结构二叉树难点

怎么通过线索二叉树查找某个数的后继结点

即形成了一个特殊的双向链表,之所以特殊,以F–>E为例,F–>E并不是直接到达,而是通过F–>B–>D–>E间接到达。

我们尝试用Java去构建一颗线索二叉树叭

先申明,我从未使用Java构建过树,二叉树都没有,若有错误,请指出

数据结点类

package com.testtree;

/**
 * @author pier
 */
public class TreeNode {
    /**数据域**/
    private int data;
    /**左指针**/
    private TreeNode left;
    /** 左孩子是否为线索,采用布尔类型主要是判断是否未null足以**/
    private boolean leftIsThread;
    /**右指针**/
    private TreeNode right;
    /** 右孩子是否为线索**/
    private boolean rightIsThread;

    /**根据数据域来确定所在的指针对应位置**/
    public TreeNode(int data)
    {
        this.data = data;
        this.left = null;
        this.leftIsThread = false;
        this.right = null;
        this.rightIsThread = false;
    }

    public int getData()
    {
        return data;
    }

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

    public TreeNode getLeft()
    {
        return left;
    }

    public void setLeft(TreeNode left)
    {
        this.left = left;
    }

    public boolean isLeftIsThread()
    {
        return leftIsThread;
    }

    public void setLeftIsThread(boolean leftIsThread)
    {
        this.leftIsThread = leftIsThread;
    }

    public TreeNode getRight()
    {
        return right;
    }

    public void setRight(TreeNode right)
    {
        this.right = right;
    }

    public boolean isRightIsThread()
    {
        return rightIsThread;
    }

    public void setRightIsThread(boolean rightIsThread)
    {
        this.rightIsThread = rightIsThread;
    }

    @Override
    public boolean equals(Object obj)
    {
        if (obj instanceof TreeNode )
        {
            TreeNode temp = (TreeNode) obj;
            if (temp.getData() == this.data)
            {
                return true;
            }
        }
        return false;
    }

    @Override
    public int hashCode()
    {
        return super.hashCode() + this.data;
    }
}

二叉树类

package com.testtree;
/*author:pier
2021/10/12
*/

public class BiTree {
    /** 根节点 **/
    private TreeNode root;
    /** 大小 **/
    private int size;
    /** 线索化的时候保存前驱 **/
    private TreeNode pre = null;

    public BiTree()
    {
        this.root = null;
        this.size = 0;
        this.pre = null;
    }

    public BiTree(int[] data)
    {
        this.pre = null;
        this.size = data.length;
        // 创建二叉树
        this.root = createTree(data, 1);
    }

    /**
     * 创建二叉树
     *
     */
    public TreeNode createTree(int[] data, int index)
    {
        if (index > data.length)
        {
            return null;
        }
        TreeNode node = new TreeNode(data[index - 1]);
        TreeNode left = createTree(data, 2 * index);
        TreeNode right = createTree(data, 2 * index + 1);
        node.setLeft(left);
        node.setRight(right);
        return node;
    }
    /**中序遍历**/
    public void inList(TreeNode root)
    {
        if (root != null)
        {
            inList(root.getLeft());
            System.out.print(root.getData() + ",");
            inList(root.getRight());
        }
    }

    public TreeNode getRoot()
    {
        return root;
    }

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

    public int getSize()
    {
        return size;
    }

    public void setSize(int size)
    {
        this.size = size;
    }
    /**线索化二叉树**/
    public void inThread(TreeNode root) {
        if ( root != null ) {
            // 线索化左孩子
            inThread(root.getLeft());
            // 左孩子为空
            if ( null == root.getLeft() )
            {
                // 将左孩子设置为线索
                root.setLeftIsThread(true);
                root.setLeft(pre);
            }
            // 右孩子为空
            if ( pre != null && null == pre.getRight() )
            {
                pre.setRightIsThread(true);
                pre.setRight(root);
            }
            pre = root;
            // 线索化右孩子
            inThread(root.getRight());
        }
    }
    /**
     * 中序遍历线索二叉树
     *
     */
    public void inThreadList(TreeNode root)
    {
        if (root != null)
        {
            // 如果左孩子不是线索
            while (root != null && !root.isLeftIsThread())
            {
                root = root.getLeft();
            }

            do
            {
                // 如果右孩子是线索
                System.out.print(root.getData() + ",");
                if (root.isRightIsThread())
                {
                    root = root.getRight();
                }
                // 有右孩子
                else
                {
                    root = root.getRight();
                    while (root != null && !root.isLeftIsThread())
                    {
                        root = root.getLeft();
                    }
                }
            } while (root != null);
        }
    }
}

测试类

package com.testtree;

/**
 * @author pier
 */
public class Test {
    public static void main(String[] args) {
    //不要问我为什么设置这么大,结尾看我效果截图
        int[] arr = new int[10000];
        for (int i = 0; i < arr.length; i++) {
            arr[i]=i+1;
        }
        //创建一颗二叉树
        BiTree biTree = new BiTree(arr);
        //中序遍历二叉树
        System.out.println("中序遍历结果如下:");
        long start1 = System.currentTimeMillis();
        biTree.inList(biTree.getRoot());
        long end1 = System.currentTimeMillis();
        System.out.println();
        System.out.println("普通遍历时间为:"+(end1-start1)+"毫秒");
        System.out.println("\n");
        //中序遍历将二叉树线索化
        biTree.inThread(biTree.getRoot());
        System.out.println("线索二叉树中序遍历如下:");
        long start2 = System.currentTimeMillis();
        biTree.inThreadList(biTree.getRoot());
        long end2 = System.currentTimeMillis();
        System.out.println();
        System.out.println("线索二叉树的遍历时间为:"+(end2-start2)+"毫秒");

    }
}

运行结果

如何理解Java数据结构二叉树难点


当我使用1-10的时候效果截图

如何理解Java数据结构二叉树难点

感谢各位的阅读,以上就是“如何理解Java数据结构二叉树难点”的内容了,经过本文的学习后,相信大家对如何理解Java数据结构二叉树难点这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

推荐阅读:
  1. 10个JavaScript难点
  2. PHP的重点和难点

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

java

上一篇:怎么隐藏Linux进程

下一篇:使用jemalloc或tcmalloc优化MYSQL的安装步骤是什么

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》