数据结构---树和二叉树
创始人
2024-04-23 23:27:07
0

树和二叉树

  • 定义
  • 二叉树
  • 二叉树的物理结构
    • 链式存储
    • 数组
  • 二叉树应用
    • 查找
    • 维持相对顺序
  • 二叉树的遍历
  • 深度优先遍历
    • 前序遍历
    • 中序遍历
    • 后序遍历
  • 二叉树广度优先遍历
    • 层序遍历

定义

  1. 有且仅有一个特定的称为根的节点。
  2. 当n>1时,其余节点可分为m(m>0)个互不相交的有限集,每一个集合本身又是一个树,并称为根的子树。
    在这里插入图片描述
    节点1是根节点(root);
    节点5、6、7、8是树的末端,没有“孩子”,被称为叶子节点(leaf)。
    图中的虚线部分,是根节点1的其中一个子树。
    节点4的上一级节点,是节点4的父节点(parent);
    从节点4衍生出来的节点,是节点4的孩子节点(child);
    和节点4同级,由同一个父节点衍生出来的节点,是节点4的兄弟节点(sibling)。
    树的最大层级数,被称为树的高度或深度。显然,上图这个树的高度是4。

二叉树

满二叉树:一个二叉树的所有非叶子节点都存在左右孩子,并且所有叶子节点都在同一层级上,那么这个树就是满二叉树。
在这里插入图片描述

完全二叉树:对一个有n个节点的二叉树,按层级顺序编号,则所有节点的编号为从1到n。如
果这个树所有节点和同样深度的满二叉树的编号为从1到n的节点位置相同,则这个
二叉树为完全二叉树。

在这里插入图片描述
完全二叉树的条件没有满二叉树那么苛刻:
满二叉树要求所有分支都是满的;而完全二叉树只需保证最后一个节点之前的节点都齐全即可

二叉树的物理结构

链式存储

在这里插入图片描述
二叉树的每一个节点包含3部分。

  1. 存储数据的data变量
  2. 指向左孩子的left指针
  3. 指向右孩子的right指针

数组

在这里插入图片描述

假设一个父节点的下标是parent,那么它的左孩子节点下标就是2×parent +1;右孩子节点下标就是2×parent + 2

反之

假设一个左孩子节点的下标是leftChild,那么它的父节点下标就是(leftChild-1)/ 2。

存在的问题:显然,对于一个稀疏的二叉树来说,用数组表示法是非常浪费空间的。

二叉堆:一种特殊的完全二叉树,就是用数组来存储的。

二叉树应用

查找

二叉查找树(二叉排序树)
如果左子树不为空,则左子树上所有节点的值均小于根节点的值
如果右子树不为空,则右子树上所有节点的值均大于根节点的值
左、右子树也都是二叉查找树
在这里插入图片描述
对于一个节点分布相对均衡的二叉查找树来说,如果节点总数是n,那么搜索节点的时间复杂度就是O(logn),和树的深度是一样的。
这种依靠比较大小来逐步查找的方式,和二分查找算法非常相似。

维持相对顺序

二叉查找树要求左子树小于父节点,右子树大于父节点,正是这样保证了二叉树的有序性。
一个问题:
在这里插入图片描述
查询节点的时间复杂度也退化成了O(n)。

解决:就涉及二叉树的自平衡了。二叉树自平衡的方式有多种,如红黑树、AVL树、树堆等

二叉树的遍历

二叉树,是典型的非线性数据结构,遍历时需要把非线性关联的节点转化成一个线性的序列,以不同的方式来遍历,遍历出的序列顺序也不同。

从节点之间位置关系的角度

  1. 前序遍历
  2. 中序遍历
  3. 后序遍历
  4. 层序遍历

从更宏观的角度

  1. 深度优先遍历(前序遍历、中序遍历、后序遍历)。
  2. 广度优先遍历(层序遍历)。

深度优先遍历

前序遍历

输出顺序是根节点、左子树、右子树
在这里插入图片描述

中序遍历

输出顺序是左子树、根节点、右子树。
在这里插入图片描述

后序遍历

输出顺序是左子树、右子树、根节点。
在这里插入图片描述

二叉树的这3种遍历方式,用递归的思路可以非常简单地实现出来

package dataStructure.binaryTree;import java.util.Arrays;
import java.util.LinkedList;public class bineryTree {//静态内部类//二叉树节点private static class TreeNode{int data;TreeNode leftChild;TreeNode rightChild;public TreeNode(int data) {this.data = data;}}/*** 前序遍历的链表节点的顺序.来创建二叉树* @param inputList* @return*/public static TreeNode precreatBinaryTree(LinkedList inputList){TreeNode node = null;if(inputList==null||inputList.isEmpty()){return null;}Integer data = inputList.removeFirst();if(data!=null){node = new TreeNode(data);node.leftChild=precreatBinaryTree(inputList);node.rightChild = precreatBinaryTree(inputList);}//将根节点返回(用于遍历,不返回根节点,这个树怎么找。。。。。)return node;}/*** 前序遍历* @param node*/public static void preOrderTraveral(TreeNode node){if(node==null){return;}System.out.println(node.data);preOrderTraveral(node.leftChild);preOrderTraveral(node.rightChild);}/*** 中序遍历* @param node*/public static void inOrderTraveral(TreeNode node){if (node==null){return;}inOrderTraveral(node.leftChild);System.out.println(node.data);inOrderTraveral(node.rightChild);}/*** 后序遍历* @param node*/public static void postOrderTraveral(TreeNode node){if (node==null){return;}postOrderTraveral(node.leftChild);postOrderTraveral(node.rightChild);System.out.println(node.data);}public static void main(String[] args) {//前序创建二叉树LinkedList inputList = new LinkedList(Arrays.asList(new Integer[]{3,2,9,null,null,10,null,null,8,null,4}));TreeNode treeNode = precreatBinaryTree(inputList);System.out.println("前序遍历");preOrderTraveral(treeNode);System.out.println("中序遍历");inOrderTraveral(treeNode);System.out.println("后序遍历");postOrderTraveral(treeNode);}
}

二叉树的构建方法有很多,这里把一个线性的链表转化成非线性的二叉树,链表节点的顺序恰恰是二叉树前序遍历的顺序。链表中的空值,代表二叉树节点的左孩子或右孩子为空的情况。
在这里插入图片描述

二叉树广度优先遍历

层序遍历

在这里插入图片描述
每个节点左侧的序号代表该节点的输出顺序。
借助队列完成二叉树层序遍历

 //队列实现public static void levelOrderTraversal(TreeNode root){Queue queue = new LinkedList();//向队列中插入元素,如果操作成功返回true,反之返回false。queue.offer(root);while (!queue.isEmpty()){//poll()返回队首元素的同时删除队首元素TreeNode node = queue.poll();System.out.println(node.data);if (node.leftChild!=null){queue.offer(node.leftChild);}if(node.rightChild!=null){queue.offer(node.rightChild);}}}

相关内容

热门资讯

门口门禁安卓系统 开源,构建便... 你有没有想过,家里的门口也能变得智能起来呢?想象当你回家时,门禁系统自动识别你的脸庞,轻轻一笑,门就...
安卓系统调节音量吗,轻松掌控手... 手机里的声音总是那么调皮,有时候太吵,有时候又太小声,真是让人头疼。别急,今天就来教你如何轻松调节安...
安卓a和b系统,深度解析两大操... 亲爱的读者们,你是否曾好奇过安卓手机里的A和B系统究竟有何不同?今天,就让我带你一探究竟,揭开这个神...
pc安装安卓5.0系统,跨越设... 你有没有想过,把手机里的安卓系统搬到电脑上,那感觉是不是就像给电脑穿上了时尚的新衣?今天,就让我带你...
安卓系统手机怎么备份,全方位备... 亲爱的手机控们,你是否也有过这样的烦恼:手机里的照片、视频、联系人、应用等数据,突然间消失得无影无踪...
侧滑手机 安卓系统,安卓系统下... 你有没有想过,手机的世界里,曾经有一群特别的“舞者”?它们就是侧滑手机,尤其是那些搭载了安卓系统的宝...
安卓系统屏幕乱跳,安卓手机屏幕... 亲爱的手机控们,你们有没有遇到过这样的烦恼:手机屏幕突然开始乱跳,就像有只小手在屏幕上乱点乱划,让人...
元气骑士支持安卓系统,畅享奇幻... 哎呀呀,你知道吗?最近我在手机上发现了一款超级好玩的游戏,它就是《元气骑士》!这款游戏不仅画面萌萌哒...
mtk安卓系统手机驱动,MTK... 你有没有遇到过这种情况:手机连接电脑时,电脑就像个“瞎子”,怎么也看不见你的宝贝手机?别急,今天就来...
安卓项目系统设计总结,安卓项目... 你有没有想过,一个安卓项目从无到有,就像是一颗种子在土壤中慢慢生根发芽,最终长成参天大树呢?今天,就...
安卓系统绑定定位,智慧生活新体... 你有没有想过,手机这小玩意儿,不仅能打电话、发短信,还能变成你的私人侦探,随时随地告诉你朋友或家人的...
安卓如何清系统数据,轻松恢复流... 亲爱的手机控们,你们是不是也和我一样,时不时地觉得手机卡顿得厉害,就像老牛拉破车一样?别急,今天就来...
华为摆脱安卓系统了吗,全面摆脱... 你有没有听说最近华为的大动作?没错,就是那个让安卓系统都黯然失色的鸿蒙系统!是不是好奇华为是不是真的...
beats耳机蓝牙 安卓系统,... 你有没有想过,那些在街头巷尾随处可见,时尚潮人们必备的Beats耳机,竟然也能和你的安卓手机愉快地“...
安卓系统为什么要用linux系... 亲爱的读者们,你是否曾好奇过,为什么安卓系统会选择拥抱Linux系统呢?这背后可是有着不少故事哦!今...
qq飞车苹果系统转安卓系统,跨... 亲爱的飞车迷们,你们是不是也有过这样的烦恼:手机从苹果换成了安卓,可心爱的QQ飞车账号却无法带过去?...
小米安卓系统隐藏彩蛋,体验科技... 哇塞,你知道吗?小米安卓系统里竟然藏着不少隐藏彩蛋,就像宝藏一样等着我们去发掘!这些彩蛋不仅让人惊喜...
然如何看安卓系统,安卓系统下的... 亲爱的手机控们,你是否曾好奇过,自己手中的安卓手机究竟运行着哪个版本的操作系统呢?别急,今天就来带你...
安卓系统关闭锁频,享受自由畅快... 手机锁屏这事儿,是不是让你头疼过?每次解锁都要输入密码,有时候手忙脚乱,简直就像是在玩解谜游戏。别急...
奥迪安卓系统如何升级,轻松提升... 亲爱的奥迪车主们,你们是不是也和我一样,对那辆爱车的智能系统充满了好奇呢?今天,就让我来带你一起探索...