算法与结构 树结构

本文介绍了树结构的基本概念和特性,包括根结点、子结点、度数等,并深入探讨了二叉树的定义、类型如满二叉树和完全二叉树。此外,还讲解了遍历二叉树的先序、中序和后序方法,包括递归和非递归实现。
摘要由CSDN通过智能技术生成
  1. 树结构:树结构是一种描述非线性层次关系的数据结构。
  • 树是n个数据结点的集合,在该集合中包含一个根结点,根结点之下分布着一些互不交叉的子集合,这些子集合是根结点的子树。

  • 树结构的基本特征:
    (1)在一个树结构中,有且只有一个结点没有直接前驱,这个结点就是树的根结点;
    (2)除根结点之外,其余每个节点有且仅有一个直接前驱;
    (3)每个结点可以有任意多个直接后继。
    在这里插入图片描述

  1. 树的概念
  • 父结点和子结点:每个结点子树的根称为该结点的子结点,相应的,该结点称为其子结点的父结点;
  • 兄弟结点:具有同一父结点的结点称为兄弟结点;
  • 结点的度:一个结点所包含子树的数量;
  • 树的度:是指该树所有结点中最大的度;
  • 叶结点:树中度为零的结点称为叶结点或终端结点;
  • 分支结点:树中度不为零的结点称为分支结点或非终端结点;
  • 结点的层数:结点的层数从树根开始计算,根结点为第1层、依次向下为第2、3、…n层(树是一种层次结构,每个结点都处在一 定的层次上);
  • 树的深度:树中结点的最大层数称为树的深度;
  • 有序树:若树中各结点的子树(兄弟结点)是按一 定次序从左向右排列的,称为有序树;
  • 无序树:若树中各结点的子树(兄弟结点)未按一 定次序排列,称为无序树;
  • 森林(forest): n (n>0)棵互不相交的树的集合。
  1. 二叉树
  • 二叉树是树结构的一种特殊形式,是n个结点的集合,每个结点最多可以有两个结点。

  • 二叉树的子树依然是二叉树。

  • 二叉树的一个结点上对应的两个子树分别称为左子树和右子树。由于二叉树子树有左右之分,故而二叉树是有序树。

  • 普通树结构中,结点的最大度数没有限制,而二叉树结点的最大度数为2。

  • 一个二叉树结构也可以是空,此时空二叉树中没有数据结点,是一个空集合。

  • 二叉树有两种特殊类型:

(1) 满二叉树:在二叉树中除了最下一层的叶结点外,每层的结点都有两个子结点
典型的满二叉树
(2) 完全二叉树:

二叉树中除最后一层外,其它各层的结点都达到最大个数,且最后一层叶结点按照左往右的顺序连续存在,只缺最后一层右侧若干结点。
在这里插入图片描述

  • 完全二叉树的性质

二叉树中树结构研究的重点是完全二叉树。对于完全二叉树,若树中包含n个结点,假设这些结点按照顺序方式存储。那么,对于任意一个结点m来说,具有如下性质:

  • 如果m!=1,则结点m的父结点的编号为m/2;
  • 如果2m≤n,则结点m的左子树根结点的编号为2m; 若2*m>n, 则无左子树,也没有右子树
  • 如果2m+1≤n, 则结点m的右子树根结点编号为2m+1;若2*m+1>n,
    则无右子树。另外,对于该完全二叉树来说,其深度为[log2n]+1。

这些基本性质展示了完全二叉树结构的特点,在完全二叉树的存储方式及运算处理上都有重要意义。

  1. 遍历二叉树
    遍历二叉树即逐个查找二叉树中的所有结点,这是二叉树的基本操作,因为很多操作都需要首先遍历整个二叉树。由于二叉树结构的特殊性,往往可以采用多种方法进行遍历。
    由于二叉树代表的是一种层次结构,因此,首先按层来遍历整个二叉树。对于二叉树的按层遍历,一般不能使用递归算法来编写代码,而是使用一个循环队列来进行处理。
    当然也可以使用递归算法来简化遍历算法。一般可以采用以下几种方法来遍历整个二叉树:
  • 先序遍历:即先访问根结点,再按先序遍历左子树,最后先序遍历右子树。

1、首先先定义一个树节点类信息,如下:

package com.dz.demo.algorithm;
 
public class TreeNode {
   
    int val;
    TreeNode left;
    TreeNode right;
 
    TreeNode(int x) {
   
        val = x;
    }
}

2、递归调用比较简单,具体如下:

    private static void preOrderRecursive(TreeNode root) {
   
        if (root == null) return;
        System.out.println(root.val);
        preOrderRecursive(root.left);
        preOrderRecursive(root.right);
    }

3、非递归的方法主要是借助栈结构来完成:

    private static void preOrderUnRecursive(TreeNode root) {
   
        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);
        while (!stack.empty(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值