树的相关概念

什么是树

​ 树( T r e e Tree Tree)是 n n n ( n ≧ 0 n ≧ 0 n0 )个结点的有限集。 n = 0 n=0 n=0 时称为空树。在任意一颗非空树中:有且仅有一个特定的称为根的结点。当 n > 1 n>1 n>1 时,其余结点可分为 m m m ( m > 0 m > 0 m>0 ) 个互不相交的有限集 T 1 T1 T1 T 2 T2 T2 T 3 T3 T3……、 T m Tm Tm,其中每个集合本身又是一棵树,并且称为根的子树。

树的基本概念
图片描述

二叉树

什么是二叉树

​ 二叉树是 n n n ( n > = 0 n>=0 n>=0) 个结点的有限集合,该集合或者为空集(空二叉树)、或者由一个根结点和两颗互不相交的、分别称为根结点的左子树和右子树的二叉树组成。

二叉树的特点

​ 1.二叉树中每个结点最多有两颗子树,度没有超过 2 2 2 的。

​ 2.左子树和右子树是有顺序的,不能颠倒。

满二叉树

​ 在二叉树中,所有的分支节点都有左子树和右子树,并且所有的叶子都在同一层。

完全二叉树

​ 1.叶子结点只能出现在最下面两层。

​ 2.最下层的叶子一定集中在左部连续位置。

​ 3.倒数第二层,若有叶子结点,一定在右部连续位置。

​ 4.如果结点度为 1$ ,则该结点只有左孩子。

​ 5.同样结点的二叉树,完全二叉树的深度最小。

二叉树的创建和嵌套打印

//结点类
public class TreeNode{
    int data;//结点存放的数据
    TreeNode left;//左孩子
    TreeNode right;//右孩子
    public TreeNode(int data,TreeNode left,TreeNOde right){
        this.data = data;
        this.left = left;
        this.right = right;
    }
}
import java.util.Scanner;
public class Tree{
    TreeNode root;//整棵树的根节点
    Scanner sc = new Scanner(System.in);
    public Tree(){
        root = null;
    }
    public TreeNode createBinaryTree(){//树的创建
        TreeNode t;//当前树的根节点
        int x = sc.nextInt();
        if(x==0) t=null;
        else{
            t = new TreeNode();
            t.data = x;
            t.left = createBinaryTree();
            t.right = createBinaryTree();
        }
        return t;
    }
    public void printTree(TreeNode t){//树的打印
        if(t!=null){
            System.out.print(t.data);
            if(t.left!=null || t.right!=null){
                System.out.print("(");
                printTree(t.left);
                if(t.right!=null) System.out.print(",");
                printTree(t.left);
                System.out.print(")");
            }
        }
    }
}

前中后序层次遍历

前序遍历

​ 思路:对于每个结点,优先处理结点本身,再处理它的左孩子,最后处理它的右孩子。

图片描述

此图结果为: A B D G H C E I F ABDGHCEIF ABDGHCEIF

public void preOrder(TreeNode root){
    if(root!=null){
        System.out.print(root.data+" ");
        preOrder(root.left);
        preOrder(root.right);
    }
}
中序遍历

​ 思路:对于每个结点,优先处理它的左孩子,再处理它本身,最后处理它的右孩子。

图片描述

此图结果为: G D H B A E I C F GDHBAEICF GDHBAEICF

public void midOrder(TreeNode root){
    if(root!=null){
        midOrder(root.left);
        System.out.print(root.data+" ");
        midOrder(root.right);
    }
}
后序遍历

​ 思路:对于每个结点,优先处理它的左节点,再处理它的右节点,最后处理它本身。

图片描述

此图结果为: G H D B I E F C A GHDBIEFCA GHDBIEFCA

public void postOrder(TreeNode root){
    if(root!=null){
        postOrder(root.left);
       	postOrder(root.right);
        System.out.print(root.data+" ");
    }
}
层次遍历

​ 思路:广度优先搜索;借助一个队列;先将二叉树根结点入队,然后出队,访问出队结点,若它有左子树,则将左子树根结点入队;若它有右子树,则将右子树根结点入队。然后出队,访问出队结…如此反复,直至队列为空。

image-20230521233612736

此图结果为: A B C D E F G H I ABCDEFGHI ABCDEFGHI

public void levelOrder(TreeNode t){
    Queue<TreeNode> queue = new LinkedList<>();
    if(t==null) return;
    queue.offer(t);
    while(!queue.isEmpty()){
        TreeNode head = queue.poll();
        System.out.print(head.data);
        if(head.left!=null)
        	queue.offer(head.left);
        if(head.right!=null)
        	queue.offer(head.right);
    }
}

求二叉树深度

public int treeDepth(TreeNode root){
    if(root==null) return 0;//此结点不存在
    return Math.max(treeDepth(root.left),treeDepth(root.right))+1;
}

求二叉树叶子结点个数

public int TreeLeaf(TreeNode root){
    if(root==null) return 0;
    if(root.left==null && root.right==null) return 1;//此结点没有孩子,表示此结点为叶子结点
    else return treeLeaf(root.left) + treeLeaf(root.right);
}

重建二叉树

​ 思路:

​ 1.前序遍历为:根,{左子树},{右子树};可得,前序遍历的第一个结点为根结点;

​ 2.中序遍历为:{左子树},根,{右子树};可得,结点的左侧为它的左孩子树,右侧为它的右孩子树;

​ 3.重复此过程,重建此二叉树(求后序遍历结果);

数据结构 二叉树的存储结构_线程二叉树| 数据结构_cumtb2002的博客-CSDN博客

​ 以此树为例:

​ 1.前序遍历为 A B D E H C F G ABDEHCFG ABDEHCFG,中序遍历为 D B H E A F C G DBHEAFCG DBHEAFCG

​ 2.前序遍历的第一个点( A A A )一定是根节点,那么中序遍历中, A A A 左边的部分( D B H E DBHE DBHE)为 A A A 的左子树,右边的部分( F C G FCG FCG )为 A A A 的右子树;

​ 3.每一个子树也都是一个完整的树,那么对于树( B D E H BDEH BDEH), B B B 是这个子树的根节点,这个子树的左子树为( D D D),右子树为( E H EH EH);对于树( C F G CFG CFG), C C C 是这个子树的根节点,这个子树的左子树为 F F F,右子树为 G G G

​ 4.重复此过程,直至每一个子树都检索完成为止,此时,树其实已经重建出来了,后序遍历也可得到(对于每一个子树,优先输出左子树,输出右子树,最后输出根节点);

public static String f(String pre,String mid){//前序遍历结果,中序遍历结果
    if(pre.length()==0) return "";
    else if(pre.length==1) return pre;
    else{
        int pos = mid.indexOf(pre.charAt(0));
        String left = f(pre.substring(1,pos+1),mid.substring(0,pos));
        String right = f(pre.substring(pos+1),mid.substring(pos+1));
        return left+right+pre.charAt(0);
    }
}

二叉排序树

​ 二叉排序树(也称二叉查找树)或者是一棵空树,或者是具有下列特性的二叉树:

​ 若左子树非空,则左子树上所有结点的值均小于根结点的值。
​ 若右子树非空,则右子树上所有结点的值均大于根结点的值。
​ 左、右子树也分别是一棵二叉排序树。
​ 根据二叉排序树的定义,左子树结点值 < < < 根结点值 < < < 右子树结点值,所以对二叉排序树进行中序遍历,可以得到一个递增的有序序列。

​ 此图二叉排序树的中序遍历序列为 123468 123468 123468

img
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值