数据结构-二叉树

树形结构

概念

树是一种非线性的数据结构 ,它是由n(n>=0)个有限节点 组成的一个具有层次关系的集合。把他叫做树是因为它看起来像一颗倒挂的树,也就是说他是跟朝上,而叶朝下的。

1.有根节点,根节点没有前驱节点 ,除了根节点之外,其余节点被分成M(M>0)个互不相交的集合 T1、T2、...... 、Tm,其中每个集合又是一颗于树类似的子树 。每棵子树的根节点 有且只有一个前驱,可有多个后继

树是递归定义的

注意: 树形结构中,字树之间不能有交集,否则就不是树形结构

概念

节点的度: 一个节点含有子树的个数,A的度为6

树的度: 一棵树中,所有节点度最大值称为树的度,上图中树的度为6

叶子节点/终端节点:度为0的节点称为叶节点,B C H....是叶子节点

双亲节点/父节点: 若一个节点含有子节点,则这个节点称为其子节点的父节点,A是B的父节点

孩子节点/子节点: 一个节点含有的子树的根节点称为该节点的子节点,B是A的子节点

根节点: 一个树中没有双亲结点的节点,A

节点的层次:根开始定义根为一层,往下依次增加

树的高度或深度:树中节点的最大层次

非终端节点:度不为0的节点

兄弟节点:BC

堂兄弟节点:双亲在同一层

节点的祖先: 从根节点到该节点所经分支上所有的节点 A是所有节点的祖先

子孙:以某一节点为根子树中任意节点都称为该节点的子孙。所有节点都是A的子孙

森林:m(m>=0)棵互不相交的树 组成的集合称为森林

树的表现形式

树有很多种表示方法,如双亲表示法,孩子表示发,孩子双亲表示法,孩子兄弟表示法 。我们这里简单了解其中最常用的孩子兄弟表示法

java 复制代码
class Node {
    int value; // 树中存储的数据
    Node firstChild; // 第一个孩子引用
    Node nextBrother; // 下一个兄弟引用
}

树的应用

文件管理系统(目录和文件)

二叉树

一颗二叉树是节点的一个有限集合,该集合:

1.或者为空

2. 或者是由一个根节点加上两颗别称为左子树和右子树的二叉树组成

从上图看出

1. 二叉树不存在度大于2 的节点

2. 二叉树的子树有左右之分,次序不能颠倒,因此二叉树是有序树

二叉树的几种组合:

特殊的二叉树

1.满二叉树: 一颗二叉树,如果每一层的节点都达到最大值 ,则这颗二叉树就是满二叉树。也就是说,如果有一颗二叉树的层数为k ,且节点总数为2^k-1,则他是满二叉树

2.完全二叉树:除了最后一层 ,其他层必须填满 ,最后层的节点要从左向右排列左侧不能 有空位,右侧可以 有空位。满二叉树 是一种特殊的完全二叉树

计算机中数组的索引通常从0 开始,所以完全二叉树的也一般用0 来表示根节点

二叉树的性质

性质一:

对于具有n个节点的完全二叉树,如果按照从上至下从左至右的顺序对所有节点从0 开始编号,则对于序号为i的节点有:

1. 若i>0 双亲序号:(i-1)/2

2.若2i+1<n,左孩子序号:2i+1,否则无左孩子

3.若2i+2<n,右孩子序号:2i+2,否则无右孩子

性质二:

任意一个二叉树度为0的节点比度为2的节点多一个

性质三:

具有n个节点的完全二叉树深度k:log2(n+1)上取整,或者log2(n) +1向下取整

性质4:

对于编号为i(i>1)的节点,其父节点编号为i/2向下取整

二叉树的存储

二叉树的存储结构分为:顺序存储和类似于链表的链式存储

链式存储

二叉树的链式存储是通过一个一个的节点引用起来的 ,常见的表示方式有二叉和三叉表示方式

java 复制代码
// 孩子表示法
class Node {
    int val; // 数据域
    Node left; // 左孩子的引用,常常代表左孩子为根的整棵左子树
    Node right; // 右孩子的引用,常常代表右孩子为根的整棵右子树
}
// 孩子双亲表示法
class Node {
    int val; // 数据域
    Node left; // 左孩子的引用,常常代表左孩子为根的整棵左子树
    Node right; // 右孩子的引用,常常代表右孩子为根的整棵右子树
    Node parent;    // 当前节点的根节点
}

二叉树遍历

范例:

遍历就是沿着某条搜索路线,依次对树中每个节点均作一次且仅作一次访问。 访问节点所做的操作 依赖于具体的应用问题(比如:打印节点的内容、节点内容加一)。

N代表节点,L代表根节点的左子树,R代表根节点的右子树

NLR:前序遍历,访问节点->根的左子树->根的右子树

java 复制代码
 public void preOrder(TreeNode root){
            if(root==null) return;
            System.out.print(root.val+" ");
            preOrder(root.left);
            preOrder(root.right);
    }

LNR:中序遍历,根的左子树->根节点->根的右子树

java 复制代码
 public void preOrder(TreeNode root){
            if(root==null) return;
            preOrder(root.left);
            System.out.print(root.val+" ");
            preOrder(root.right);
    }

LRN:后序遍历,根的左子树->根的右子树->根节点

java 复制代码
 public void preOrder(TreeNode root){
            if(root==null) return;
            preOrder(root.left);
            preOrder(root.right);
            System.out.print(root.val+" ");
    }

**层序遍历:**由上到下,由左到右依次遍历

java 复制代码
       void levelOrder (TreeNode root){
            if(root==null) return;
            Queue<TreeNode> tmp=new LinkedList<>();
            tmp.offer(root);
            while(!tmp.isEmpty()){
                TreeNode cur=tmp.poll();
                System.out.print(cur.data+" ");
                if(cur.left!=null) tmp.offer(cur.left);
                if(cur.right!=null) tmp.offer(cur.right);
            }
            System.out.println();
        }

二叉树的基本操作

二叉树的创建

思路一:通过输入字符串递归创建

java 复制代码
 private TreeNode creatTree(String str){
        char c=str.charAt(i);
        TreeNode root=null;
        if(c!='#'){
            root=new TreeNode(c);
            i++;
            root.left=creatTree(str);
            root.right=creatTree(str);
        }else{
            i++;
        }
        return root;
    }

思路二:一个一个手动创建

获取树中节点个数

思路一:遍历二叉树,只要根节点不为空,计数器加一

java 复制代码
 public static int nodesize;
    public void size(TreeNode root){
        if(root==null) return ;
        nodesize++;
        size(root.left);
        size(root.right);
    }

思路二:分成子问题,整棵树的节点=左子树的节点+右子树的节点+1,左子树和右子树又分别当作根节点

java 复制代码
public int size(TreeNode root){
        if(root==null) return 0;
        return size(root.left)+size(root.right)+1;
    }

获取叶子节点的个数

思路一:遍历二叉树,当左右节点均为空时,计数器加一

java 复制代码
  public static int leafCount;
    public void getLeafNodeCount(TreeNode root){
        if(root==null)  return;
        if(root.left==null&&root.right==null) leafCount++;
        getLeafNodeCount(root.left);
        getLeafNodeCount(root.right);
    }

思路二:分成子问题,左节点的叶子加上右节点的叶子

java 复制代码
    public int getLeafNodeCount(TreeNode root){
        if(root==null)  return 0;
        if(root.left==null&&root.right==null) return 1;
        return getLeafNodeCount(root.left)+
        getLeafNodeCount(root.right);
    }

获取第k层节点的个数

思路一:遍历二叉树

java 复制代码
  public static int leafCount;
    public void getKLevelNodeCount(TreeNode root,int k){
       if(root==null) return ;
       if(k==1) leafCount++;
       getKLevelNodeCount(root.left,k-1);
        getKLevelNodeCount(root.right,k-1);
    }

思路二:分成子问题

java 复制代码
    public int getKLevelNodeCount(TreeNode root,int k){
       if(root==null) return 0;
       if(k==1) return 1;
       return getKLevelNodeCount(root.left,k-1)+
        getKLevelNodeCount(root.right,k-1);
    }

获取二叉树的高度

思路:左树的高度与右树的高度的最大值+1

java 复制代码
    public int getHeight(TreeNode root){
        if(root==null) return 0;
        int left=getHeight(root.left);
        int right=getHeight(root.right);
        if(left>right) return left+1;
        return right+1;
    }

时间复杂度:O(N)

空间复杂度:O(logN) 树的高度

检测某个元素是否存在

依次遍历二叉树

java 复制代码
   TreeNode find(TreeNode root, char val){
       if(root==null) return null;
       if(root.val==val) return root;
       TreeNode t1=find(root.left,val);
       if(t1!=null) return t1;
       TreeNode t2= find(root.right,val);
       if(t2!=null) return t2;
       return null;
   }

时间复杂度:O(N)

空间复杂度:O(logN)

相关推荐
学IT的周星星2 小时前
SpringMVC请求参数的绑定
java·开发语言
无妄无望2 小时前
ragflow代码学习切片方式(1)docling_parser.py
人工智能·python·学习
HUTAC2 小时前
重要排序算法(更新ing)
数据结构·算法
冉佳驹2 小时前
数据结构 ——— 八大排序算法的思想及其实现
c语言·数据结构·排序算法·归并排序·希尔排序·快速排序·计数排序
一 乐2 小时前
宠物猫店管理|宠物店管理|基于Java+vue的宠物猫店管理管理系统(源码+数据库+文档)
java·前端·数据库·vue.js·后端·宠物管理
r***99822 小时前
在2023idea中如何创建SpringBoot
java·spring boot·后端
熊猫比分管理员2 小时前
【全栈源码解决方案】Vue+Java四端齐全,一周交付可运行项目!
java·前端·vue.js
chen_note2 小时前
K8s的配置存储与实战
java·容器·kubernetes·volume·k8s存储
i***39582 小时前
ShardingSphere-jdbc 5.5.0 + spring boot 基础配置 - 实战篇
java·spring boot·后端