二叉树小结(附Java代码可直接运行)

二叉树常见类型

1、满二叉树

一棵二叉树的结点要么是叶子结点,要么它有两个子结点(如果一个二叉树的层数为K,且结点总数是(2^k) -1,则它就是满二叉树。)
在这里插入图片描述
层数与此层节点数的对应关系:第K层,节点数为2^(K)。K从0开始。
计算公式
公式1
等比数列求和公式
在这里插入图片描述
最终得出
在这里插入图片描述

2、完全二叉树

若设二叉树的深度为k,除第 k 层外,其它各层 (1~k-1) 的结点数都达到最大个数,第k 层所有的结点都连续集中在最左边,这就是完全二叉树。
在这里插入图片描述

3、平衡二叉树

它或者是一颗空树,或它的左子树和右子树的深度之差(平衡因子)的绝对值不超过1,且它的左子树和右子树都是一颗平衡二叉树。
在这里插入图片描述

4、二叉搜索树

它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树
在这里插入图片描述

5、 红黑树

平衡二叉搜索树
在这里插入图片描述

6、最优二叉树(哈夫曼树)

树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。

注意点
感觉最常用的就是前5种,尤其是搜索二叉树,在进行树的相关操作时,需要利用树的定义来解题。

遍历方式

1.前序遍历

前序遍历(DLR,data,lchild,rchild),是二叉树遍历的一种,也叫做先根遍历、先序遍历、前序周游,可记做根左右。前序遍历首先访问根结点然后遍历左子树,最后遍历右子树。

2.中序遍历

中序遍历(LDR)是 二叉树遍历的一种,也叫做 中根遍历、中序周游。在二叉树中,先左后根再右。

3.后序遍历

后序遍历(LRD)是 二叉树遍历的一种,也叫做 后根遍历、后序周游,先左后右再根。

4.层次遍历

与树的前中后序遍历的DFS思想不同,层次遍历用到的是BFS思想。一般DFS用递归去实现(也可以用栈实现),BFS需要用队列去实现。
层次遍历的步骤是:
1.对于不为空的结点,先把该结点加入到队列中
2.从队中拿出结点,如果该结点的左右结点不为空,就分别把左右结点加入到队列中
3.重复步骤2直到队列为空

import org.junit.Test;
import sun.reflect.generics.tree.Tree;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}
/**
 * @author shkstart
 * @create 2021-03-03 10:49
 */
public class BinaryTree {
    /**
     * 生成一个满二叉树(也是搜索二叉树)
     * @return
     */
    public TreeNode[] createBinaryTree(){
        TreeNode[] node =new TreeNode[15];
        for(int i=0; i<node.length;i++){
            node[i] = new TreeNode(i);
        }
        for(int i=0;(2*i+1)<node.length;i++){
            node[i].left = node[2*i+1];
            if(2*i+2< node.length){
                node[i].right = node[2*i+2];
            }
        }
        return node;
    }

    /**
     * 递归前序遍历
     * @return
     */
    public List<TreeNode> preOrder(TreeNode root,List<TreeNode> res){
        if(root==null) return null;
        res.add(root);
        preOrder(root.left,res);
        preOrder(root.right,res);
        return res;
    }

    /**
     * 递归中序遍历
     * @param root
     * @param res
     * @return
     */
    public  List<TreeNode> inOrder(TreeNode root, List<TreeNode> res){
        if(root==null) return null;
        inOrder(root.left,res);
        res.add(root);
        inOrder(root.right,res);
        return res;
    }

    /**
     * 递归后序遍历
     * @param root
     * @param res
     * @return
     */
    public  List<TreeNode> lastOrder(TreeNode root, List<TreeNode> res){
        if(root==null) return null;
        lastOrder(root.left,res);
        lastOrder(root.right,res);
        res.add(root);
        return res;
    }

    /**
     * 层序遍历BFS
     * @param root
     * @return
     */
    public  List<List<Integer>> layerOrder(TreeNode root){
        if(root==null){ return null; }
        List<List<Integer>> res = new ArrayList<>();
        Queue<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        while(!queue.isEmpty()){
            List<Integer> tmp = new LinkedList<>();
            for(int n = queue.size();n>0;n--){
                TreeNode node = queue.poll();
                tmp.add(node.val);
                if(node.left!=null){ queue.add(node.left); }
                if(node.right!=null){ queue.add(node.right); }
            }
            res.add(tmp);
        }
        return res;
    }
    @Test
    public  void Test1()
    {
        System.out.println("-------创建满二叉树-------");
        TreeNode[] binaryTree = createBinaryTree();
        for(TreeNode node: binaryTree){
            System.out.print(node.val+" ");
        }
        System.out.println(" ");
        System.out.println("------前序遍历--------");
        List<TreeNode> resPre = new LinkedList<>();
        List<TreeNode> treeNodePre = preOrder(binaryTree[0],resPre);
        for(TreeNode node: treeNodePre){
            System.out.print(node.val+" ");
        }
        System.out.println("");
        System.out.println("-------中序遍历-------");
        List<TreeNode> resMid = new LinkedList<>();
        List<TreeNode> treeNodesMid = inOrder(binaryTree[0],resMid);
        for(TreeNode node: treeNodesMid){
            System.out.print(node.val+" ");
        }
        System.out.println("");
        System.out.println("-------后序遍历-------");
        List<TreeNode> resLast = new LinkedList<>();
        List<TreeNode> treeNodesLast = lastOrder(binaryTree[0],resLast);
        for(TreeNode node: treeNodesLast){
            System.out.print(node.val+" ");
        }
        System.out.println("");
        System.out.println("-------层序遍历-------");
        List<List<Integer>> treeNodesLayer = layerOrder(binaryTree[0]);
        for (List list : treeNodesLayer) {
            for (Object o : list) {
                System.out.print(o+" ");
            }
            System.out.println(" ");
        }
    }
}

之后有关树的相关知识将会在本博客持续更新~,暂时先写这么多。
参考博客:

  1. https://blog.csdn.net/coder__666/article/details/80349039
  2. https://www.cnblogs.com/-citywall123/p/11788764.html
  3. https://blog.csdn.net/linjpg/article/details/80910806
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值