清晰易懂的二叉树

一、二叉树就是这么简单
本文撇开一些非常苦涩、难以理解的概念来讲讲二叉树,仅入门观看(或复习)…

在此声明感谢原博主的文章, 原博主连接 。https://blog.csdn.net/Java_3y/article/details/79674656

首先,我们来讲讲什么是树:

树是一种非线性的数据结构,相对于线性的数据结构(链表、数组)而言,树的平均运行时间更短(往往与树相关的排序时间复杂度都不会高)
在现实生活中,我们一般的树长这个样子的:

但是在编程的世界中,我们一般把树**“倒”**过来看,这样容易我们分析:

一般的树是有很多很多个分支的,分支下又有很多很多个分支,如果在程序中研究这个会非常麻烦。因为本来树就是非线性的,而我们计算机的内存是线性存储的,太过复杂的话我们无法设计出来的。

因此,我们先来研究简单又经常用的—> 二叉树

1.1树的一些概念
我就拿上面的图来进行画来讲解了:

二叉树的意思就是说:每个节点不能多于有两个儿子,上面的图就是一颗二叉树。

一棵树至少会有一个节点(根节点)
树由节点组成,每个节点的数据结构是这样的:
因此,我们定义树的时候往往是**->定义节点->节点连接起来就成了树**,而节点的定义就是:一个数据、两个指针(如果有节点就指向节点、没有节点就指向null)


1.2静态创建二叉树
上面说了,树是由若干个节点组成,节点连接起来就成了树,而节点由一个数据、两个指针组成

因此,创建树实际上就是创建节点,然后连接节点
首先,使用Java类定义节点:


下面我们就拿这个二叉树为例来构建吧:

为了方便构建,我就给了它一个带参数的构造方法和set、get方法了:


那么我们现在就创建了5个节点:


它们目前的状态是这样子的:

于是下面我们去把它连起来:


连接完之后,那么我们的树就创建完成了。

1.3遍历二叉树
上面说我们的树创建完成了,那怎么证明呢??我们如果可以像数组一样遍历它(看它的数据),那就说明它创建完成了~

值得说明的是:二叉树遍历有三种方式

先序遍历
先访问根节点,然后访问左节点,最后访问右节点(根->左->右)
中序遍历
先访问左节点,然后访问根节点,最后访问右节点(左->根->右)
后序遍历
先访问左节点,然后访问右节点,最后访问根节点(左->右->根)
以上面的二叉树为例:

如果是先序遍历:10->9->20->15->35
如果是中序遍历:9->10->15->20->35
可能需要解释地方:访问完10节点过后,去找的是20节点,但20下还有子节点,因此先访问的是20的左儿子15节点。由于15节点没有儿子了。所以就返回20节点,访问20节点。最后访问35节点
如果是后序遍历:9->15->35->20->10
可能需要解释地方:先访问9节点,随后应该访问的是20节点,但20下还有子节点,因此先访问的是20的左儿子15节点。由于15节点没有儿子了。所以就去访问35节点,由于35节点也没有儿子了,所以返回20节点,最终返回10节点
一句话总结:先序(根->左->右),中序(左->根->右),后序(左->右->根)。如果访问有孩子的节点,先处理孩子的,随后返回

无论先中后遍历,每个节点的遍历如果访问有孩子的节点,先处理孩子的(逻辑是一样的)

因此我们很容易想到递归
递归的出口就是:当没有子节点了,就返回
因此,我们可以写出这样的先序遍历代码:


结果跟我们刚才说的是一样的:

我们再用中序遍历调用一遍吧:


结果跟我们刚才说的是一样的:

有意思的是:通过先序和中序或者中序和后序我们可以还原出原始的二叉树,但是通过先序和后续是无法还原出原始的二叉树的

也就是说:通过中序和先序或者中序和后序我们就可以确定一颗二叉树了!


二、动态创建二叉树
上面我们是手动创建二叉树的,一般地:都是给出一个数组给你,让你将数组变成一个二叉树,此时就需要我们动态创建二叉树了。

二叉树中还有一种特殊的二叉树:二叉查找树(binary search tree)

定义:当前根节点的左边全部比根节点小,当前根节点的右边全部比根节点大。
明眼人可以看出,这对我们来找一个数是非常方便快捷的
往往我们动态创建二叉树都是创建二叉查找树

2.1动态创建二叉树体验
假设我们有一个数组: int[] arrays = {3, 2, 1, 4, 5};

那么创建二叉树的步骤是这样的:

首先将3作为根节点


随后2进来了,我们跟3做比较,比3小,那么放在3的左边


随后1进来了,我们跟3做比较,比3小,那么放在3的左边,此时3的左边有2了,因此跟2比,比2小,放在2的左边


随后4进来了,我们跟3做比较,比3大,那么放在3的右边


随后5进来了,我们跟3做比较,比3大,那么放在3的右边,此时3的右边有4了,因此跟4比,比4大,放在4的右边


那么我们的二叉查找树就建立成功了,无论任何一颗子树,左边都比根要小,右边比根要大

2.2代码实现
我们的代码实现也很简单,如果比当前根节点要小,那么放到当前根节点左边,如果比当前根节点要大,那么放到当前根节点右边。

因为是动态创建的,因此我们得用一个类来表示根节点

比较与根谁大,大的往右边,小的往左边:

测试代码:


三、查询二叉查找树相关
3.1查询树的深度
查询树的深度我们可以这样想:左边的子树和右边的字数比,谁大就返回谁,那么再接上根节点+1就可以了


3.1查询树的最大值
从上面先序遍历二叉查找树的时候,细心的同学可能会发现:中序遍历二叉查找树得到的结果是排好顺序的~

那么,如果我们的二叉树不是二叉查找树,我们要怎么查询他的最大值呢?

可以这样:

左边找最大值->递归
右边找最大值->递归


四、最后
无论是在遍历树、查找深度、查找最大值都用到了递归,递归在非线性的数据结构中是用得非常多的…

树的应用也非常广泛,此篇简单地说明了树的数据结构,高级的东西我也没弄懂,可能以后用到的时候会继续深入…

 

常用的数据结构有4种:

  1. 集合。2.线性结构。3.树形结构。4.图状结构;

1.集合

数据结构中的元素之间除了“同属一个集合” 的相互关系外,别无其他关系;

2.线性结构。

常用的线性结构有:线性表,栈,队列,双队列,数组,串。

数据结构中的元素存在一对一的相互关系。

3.树形结构

树形结构是一层次的嵌套结构。 一个树形结构的外层和内层有相似的结构, 所以这种结构多可以递归的表示。经典数据结构中的各种树状图是一种典型的树形结构:一颗树可以简单的表示为根, 左子树, 右子树。 左子树和右子树又有自己的子树。

4.图状结构

图状结构,简称“图”,是一种复杂的数据结构。图状结构中,每个结点的前驱结点数和后续结点数可以任意多个。数据元素间的关系是任意的。其他数据结构(如树、线性表等)都有明确的条件限制,而图形结构中任意两个数据元素间均可相关联。

 

根据数据元素间关系的不同特性,将数据结构常分为下列四类基本的结构:
  ⑴集合结构。该结构的数据元素间的关系是“属于同一个集合”。
  ⑵线性结构。该结构的数据元素之间存在着一对一的关系。
  ⑶树型结构。该结构的数据元素之间存在着一对多的关系。
  ⑷图形结构。该结构的数据元素之间存在着多对多的关系,也称网状结构。
  数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率。

--------------------- 
作者:Java3y 
来源:CSDN 
原文:https://blog.csdn.net/java_3y/article/details/79674656 
版权声明:本文为博主原创文章,转载请附上博文链接!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值