广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Java数据结构二叉树难点解析
  • 538
分享到

Java数据结构二叉树难点解析

2024-04-02 19:04:59 538人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

前言 本章,我们主要需要了解以下内容 什么是线索二叉树 怎么去把二叉树线索化 怎么通过线索二叉树查找某个数的后继结点 二叉树的查看——二叉树怎们遍历

前言

本章,我们主要需要了解以下内容

  • 什么是线索二叉树
  • 怎么去把二叉树线索化
  • 怎么通过线索二叉树查找某个数的后继结点
  • 二叉树的查看——二叉树怎们遍历

 什么是线索二叉树

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

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

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

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

  • 线索二叉树能线性地遍历二叉树,从而比递归的中序遍历更快。使用线索二叉树也能够方便的找到一个节点的父节点,这比显式地使用父亲节点指针或者栈效率更高。这在栈空间有限,或者无法使用存储父节点的栈时很有作用(对于通过深度优先搜索来查找父节点而言)。

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

  • 为了解决无法直接找到该结点在某种遍历序列中的前驱和后继结点的问题
  • 但是同时出现了二叉链表找左、右孩子困难的问题,即在构建线索二叉树之后,链表的原来遍历方式会出问题。

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

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

线索二叉树

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

怎么去把二叉树线索化

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

  • 前序遍历二叉树的递归定义(根左右)
  • 中序遍历二叉树的递归定义(左根右)
  • 后续遍历二叉树的递归意义(左右根)

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

中序遍历

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

先画线索二叉树

在这里插入图片描述

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

线索二叉树

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

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

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

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

数据结点类


package com.testtree;


public class Treenode {
    
    private int data;
    
    private TreeNode left;
    
    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;


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;


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)+"毫秒");

    }
}

运行结果

结果


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

截图

完全看不出来差距,所以,哈哈才设置那么大,能够实践出来线索二叉树的遍历速度确实更快的。

Ps:看完这篇文章,你不来点个赞吗?不来个三连吗?重点是,你今天Get到了吗?别之后ALT+Insert自动生成get哟,用你那看起来不聪明的小脑袋瓜想一想。

到此这篇关于Java数据结构二叉树难点解析的文章就介绍到这了,更多相关Java 二叉树内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Java数据结构二叉树难点解析

本文链接: https://www.lsjlt.com/news/155397.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java数据结构二叉树难点解析
    前言 本章,我们主要需要了解以下内容 什么是线索二叉树 怎么去把二叉树线索化 怎么通过线索二叉树查找某个数的后继结点 二叉树的查看——二叉树怎们遍历...
    99+
    2022-11-12
  • 【Java 数据结构】树和二叉树
    篮球哥温馨提示:编程的同时不要忘记锻炼哦! 一棵倒立过来的树.  目录 1、什么是树? 1.1 简单认识树  1.2 树的概念  1.3 树的表示形式 2、二叉树 2.1 二叉树的概念 2.2 特殊的二叉树...
    99+
    2023-09-17
    算法 数据结构
  • 详解Java数据结构之平衡二叉树
    目录什么是二叉搜索树平衡二叉搜索树平衡二叉搜索树建树程序计算每个节点的高度计算每个节点的平衡因子合并二叉树旋转调整函数整体代码什么是二叉搜索树 简单来说,就是方便搜索的二叉树,是一种...
    99+
    2022-11-13
  • Java数据结构之二叉搜索树详解
    目录前言性质实现节点结构初始化插入节点查找节点删除节点最后前言 今天leetcode的每日一题450是关于删除二叉搜索树节点的,题目要求删除指定值的节点,并且需要保证二叉搜索树性质不...
    99+
    2022-11-13
  • Java数据结构学习之二叉树
    一、背景知识:树(Tree) 在之前的笔记中,我们介绍的链表、栈、队列、数组和字符串都是以线性结构来组织数据的。本篇笔记要介绍的树采用的是树状结构,这是一种非线性的数据组织形式。 树...
    99+
    2022-11-12
  • java数据结构之搜索二叉树
    本文实例为大家分享了java数据结构之搜索二叉树的具体代码,供大家参考,具体内容如下 搜索二叉树的定义是:在一个二叉树上,左节点一定比父节点小,右节点一定比父节点大,其他定义跟二叉树...
    99+
    2022-11-12
  • Java数据结构超详细分析二叉搜索树
    目录1.搜索树的概念2.二叉搜索树的简单实现2.1查找2.2插入2.3删除2.4修改3.二叉搜索树的性能 1.搜索树的概念 二叉搜索树是一种特殊的二叉树,又称二叉查找树,二叉排序树,...
    99+
    2022-11-13
  • Java数据结构之二叉搜索树实例分析
    这篇文章主要介绍“Java数据结构之二叉搜索树实例分析”,在日常操作中,相信很多人在Java数据结构之二叉搜索树实例分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java数据结构之二叉搜索树实例分析”的疑...
    99+
    2023-06-30
  • 数据结构之链式二叉树详解
    目录🍏1.二叉树的遍历🍏1.1前序遍历1.2中序遍历1.3后序遍历1.4层次遍历 🍎2.链式二叉树的实现🍎2.1二叉树的创建2.2前序遍历2.3中序遍历2.4后序遍历2.5...
    99+
    2023-05-16
    C语言链式二叉树 数据结构链式二叉树 C语言 数据结构
  • JavaScript数据结构与算法之二叉树插入节点、生成二叉树的示例分析
    小编给大家分享一下JavaScript数据结构与算法之二叉树插入节点、生成二叉树的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解...
    99+
    2022-10-19
  • Java 数据结构进阶二叉树题集下
    目录1、对称二叉树2、创建并遍历二叉树3、二叉树中两节点最近公共祖先4、二叉搜索树与双向链表5、根据前序和中序遍历结果创建二叉树6、二叉树创建字符串7、非递归实现二叉树前序遍历8、非...
    99+
    2022-11-13
  • Java数据结构进阶二叉树题集上
    目录1、二叉树的遍历(1)前、中、后序遍历(2)层序遍历2、获取树中子结点的个数3、获取二叉树的高度4、判断是不是完全二叉树5、判断两个树是否相同6、另一棵树的子树7、判断平衡二叉树...
    99+
    2022-11-13
  • C语言数据结构之二叉树详解
    目录1. 树概念及结构1.1树概念1.2树的表示2. 二叉树概念及结构2.1概念2.2数据结构中的二叉树2.3特殊的二叉树2.4二叉树的存储结构2.5二叉树的性质3. 二叉树顺序结构...
    99+
    2022-11-13
  • Java数据结构之平衡二叉树的实现详解
    目录定义结点结构查找算法插入算法LL 型RR 型LR 型RL 型插入方法删除算法概述实例分析代码完整代码定义 动机:二叉查找树的操作实践复杂度由树高度决定,所以希望控制树高,左右子...
    99+
    2022-11-13
  • 带你了解Java数据结构和算法之二叉树
    目录1、树2、二叉树3、查找节点4、插入节点5、遍历树6、查找最大值和最小值7、删除节点  ①、删除没有子节点的节点②、删除有一个子节点的节点③、删除有两个子节点的节点④、删除有必要...
    99+
    2022-11-13
  • Go 数据结构之二叉树详情
    目录Go 语言实现二叉树定义二叉树的结构二叉树遍历创建二叉树插入值测试前言: 树可以有许多不同的形状,并且它们可以在每个节点允许的子节点数量或它们在节点内组织数据值的方式上有所不同。...
    99+
    2022-11-13
  • Java数据结构之二叉排序树的实现
    目录1 二叉排序树的概述2 二叉排序树的构建2.1 类架构2.2 查找的方法2.3 插入的方法2.4 查找最大值和最小值2.5 删除的方法3 二叉排序树的总结1 二叉排序树的概述 本...
    99+
    2022-11-13
  • Java数据结构之二叉查找树的实现
    目录定义节点结构查找算法插入算法删除算法完整代码定义 二叉查找树(亦称二叉搜索树、二叉排序树)是一棵二叉树,且各结点关键词互异,其中根序列按其关键词递增排列。 等价描述:二叉查找树中...
    99+
    2022-11-13
  • 【Java 数据结构】实现一个二叉搜索树
    目录  1、认识二叉搜索树 2、实现一个二叉搜索树 2.1 成员变量 2.2 insert 方法 2.3 search 方法  2.4 remove 方法(重点) 3、二叉搜索树总结 1、认识二叉搜索树 从字面上来看,它只比二叉树多...
    99+
    2023-09-02
    数据结构 算法 二叉搜索树
  • C语言数据结构详细解析二叉树的操作
    目录二叉树分类二叉树性质性质的使用二叉树的遍历前序遍历中序遍历后序遍历层序遍历求二叉树的节点数求二叉树叶子结点个数求二叉树的最大深度二叉树的销毁二叉树分类 满二叉树 除最后一层无任何...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作