树学习总结

1.基础知识

1.1 常用术语

  • 节点
  • 根节点
  • 父节点
  • 子节点
  • 叶子节点
  • 节点的权(节点的值)
  • 路径 (从root节点找到该节点的路线)
  • 子树
  • 树的高度(最大层数)
  • 森林(多课子树可构成森林)

1.2 二叉树

  • 二叉树概念:每个节点最多只能有两个子节点的一种形式称为二叉树
  • 二叉树的左子节点和右子节点
  • 如果该二叉树的所有叶子节点都在最后一层,并且叶子节点总数=2(n-1) (所有节点总数 = 2n -1),n为层数,则我们称为满二叉树
  • 如果该二叉树的所有叶子节点都在最后一层或者倒数第二层,最后一层的叶子节点在左边连续,倒数第二层的叶子节点在右边连续,我们称为完全二叉树。(满二叉树是一种特殊的完全二叉树)

1.3 二叉树的遍历、查找、删除

  • 前序遍历: 左 右
  • 中序遍历:左
  • 后序遍历:左 右

遍历代码


package Package01;

public class BinaryTree {
    public static void main(String[] args) {
        //先需要创建一棵二叉树
        BinaryTreee binaryTreee = new BinaryTreee();
        HeroNode root = new HeroNode(1,"宋江");
        HeroNode node2 = new HeroNode(2,"吴用");
        HeroNode node3 = new HeroNode(3,"卢俊义");
        HeroNode node4 = new HeroNode(4,"林冲");
        //我们先手动创建二叉树,后面再使用递归创建二叉树
        root.setLeft(node2);
        root.setRight(node3);
        node3.setRight(node4);
        binaryTreee.setRoot(root);
        //测试
        System.out.println("前序遍历" );
        binaryTreee.preOrder();
        
        

    }


}

//定义一个BinaryTree
class BinaryTreee{
    public HeroNode root;

    public void setRoot(HeroNode root) {
        this.root = root;
    }
    //前序遍历
    public void preOrder(){
        if(this.root!=null){
            this.root.preOrder();
        }else{
            System.out.println("二叉树为空,无法遍历");
        }
    }
    //中序遍历
    public void infixOrder(){
        if(this.root!=null){
            this.root.infixOrder();
        }else{
            System.out.println("二叉树为空,无法遍历");
        }
    }
    //后序遍历
    public void postOrder(){
        if(this.root!=null){
            this.root.postOrder();
        }else{
            System.out.println("二叉树为空,无法遍历");
        }
    }
}


//先创建HeroNode节点
class HeroNode{
    private int no;
    private String name;
    private HeroNode left;  //默认为nul,不需要写在构造函数里面
    private HeroNode right; //默认为null,不需要写在构造函数里面

    public HeroNode(int no, String name){
        super();
        this.no = no;
        this.name = name;
    }

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public HeroNode getLeft() {
        return left;
    }

    public void setLeft(HeroNode left) {
        this.left = left;
    }

    public HeroNode getRight() {
        return right;
    }

    public void setRight(HeroNode right) {
        this.right = right;
    }

    @Override
    public String toString() {
        return "HeroNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                '}';
    }

    //编写前序遍历的方法
    public void preOrder(){
        System.out.println(this);   //先输出父节点
        //递归向左子树遍历
        if(this.left!=null){
            this.left.preOrder();
        }
        //递归向右子树
        if(this.right!=null){
            this.right.preOrder();
        }

    }

    //中序遍历

    public void infixOrder(){
        //首先递归向左子树
        if(this.left!=null){
            this.left.infixOrder();
        }
        //输出父节点
        System.out.println(this);
        //递归向右子树
        if(this.right!=null){
            this.right.infixOrder();
        }

    }

    //后序遍历

    public void postOrder(){
        //先遍历左子节点
        if(this.left!=null){
            this.left.postOrder();
        }
        //再遍历右子节点
        if(this.right!=null){
            this.right.postOrder();
        }
        //输出父节点
        System.out.println(this);

    }




}


查找代码


//  二叉树-查找指定的节点
//要求:   1. 请编写前序查找,中序查找和后序查找的方法
//	      2. 并分别使用三种查找方法,查找heroNOde5的节点
//        3. 并分析各种查找方式,分别比较了多少次

package Package01;

public class BinaryTree {
    public static void main(String[] args) {
        //需要创建一棵二叉树,首先要创建二叉树的节点
        BinaryTreee binaryTreee = new BinaryTreee();
        HeroNode root = new HeroNode(1,"宋江");
        HeroNode node2 = new HeroNode(2,"吴用");
        HeroNode node3 = new HeroNode(3,"卢俊义");
        HeroNode node4 = new HeroNode(4,"林冲");


        //我们先手动创建二叉树,将节点之间连接起来,后面再使用递归创建二叉树
        root.setLeft(node2);
        root.setRight(node3);
        node3.setRight(node4);
        binaryTreee.setRoot(root);


        //测试遍历
        System.out.println("++++++++++ 测试遍历 ++++++++++");
        System.out.println("前序遍历:" );
        binaryTreee.preOrder();
        System.out.println("中序遍历:" );
        binaryTreee.infixOrder();
        System.out.println("后序遍历:" );
        binaryTreee.postOrder();


        //测试查找
        System.out.println();
        System.out.println("++++++++++ 测试查找 ++++++++++");
        System.out.println("前序查找:");
        HeroNode resNode = binaryTreee.preOrderSearch(4);
        if(resNode != null){
            System.out.printf("找到了,信息为no=%d name=%s",resNode.getNo(),resNode.getName());
        }else{
            System.out.printf("没有找到no = %d 的英雄",4);
        }


    }


}

//定义一个BinaryTree
class BinaryTreee{
    public HeroNode root;

    public void setRoot(HeroNode root) {
        this.root = root;
    }
    //前序遍历
    public void preOrder(){
        if(this.root!=null){
            this.root.preOrder();
        }else{
            System.out.println("二叉树为空,无法遍历");
        }
    }
    //中序遍历
    public void infixOrder(){
        if(this.root!=null){
            this.root.infixOrder();
        }else{
            System.out.println("二叉树为空,无法遍历");
        }
    }
    //后序遍历
    public void postOrder(){
        if(this.root!=null){
            this.root.postOrder();
        }else{
            System.out.println("二叉树为空,无法遍历");
        }
    }

    //前序查找

    /**
     *
     * @param no
     * @return
     */
    public HeroNode preOrderSearch(int no){
        if(root != null){
            return root.postOrderSearch(no);
        }else{
            return null;
        }
    }

    //中序查找

    /**
     *
     * @param no
     * @return
     */
    public HeroNode infixOrderSearch(int no){
        if(root != null){
            return root.infixOrderSearch(no);
        }else{
            return null;
        }
    }

    //后序查找

    /**
     *
     * @param no
     * @return
     */
    public HeroNode postOrsearSearch(int no){
        if(root != null){
            return root.infixOrderSearch(no);
        }else{
            return null;
        }
    }




}


//先创建HeroNode节点
class HeroNode{
    private int no;
    private String name;
    private HeroNode left;  //默认为nul,不需要写在构造函数里面
    private HeroNode right; //默认为null,不需要写在构造函数里面

    public HeroNode(int no, String name){
        super();
        this.no = no;
        this.name = name;
    }

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public HeroNode getLeft() {
        return left;
    }

    public void setLeft(HeroNode left) {
        this.left = left;
    }

    public HeroNode getRight() {
        return right;
    }

    public void setRight(HeroNode right) {
        this.right = right;
    }

    @Override
    public String toString() {
        return "HeroNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                '}';
    }

    //编写前序遍历的方法
    public void preOrder(){
        System.out.println(this);   //先输出父节点
        //递归向左子树遍历
        if(this.left!=null){
            this.left.preOrder();
        }
        //递归向右子树
        if(this.right!=null){
            this.right.preOrder();
        }

    }

    //中序遍历

    /**
     *
     */
    public void infixOrder(){
        //首先递归向左子树
        if(this.left!=null){
            this.left.infixOrder();
        }
        //输出父节点
        System.out.println(this);
        //递归向右子树
        if(this.right!=null){
            this.right.infixOrder();
        }

    }

    //后序遍历

    /**
     *
     */
    public void postOrder(){
        //先遍历左子节点
        if(this.left!=null){
            this.left.postOrder();
        }
        //再遍历右子节点
        if(this.right!=null){
            this.right.postOrder();
        }
        //输出父节点
        System.out.println(this);

    }



    //前序遍历查找

    /**
     *
     * @param no 查找的no
     * @return   如果找到就返回该Node,没有找到就返回null
     */
    public HeroNode preOrderSearch(int no){
        //比较当前节点是不是no
        if(this.no==no){
            return this;
        }
        //如果不是,则判断当前节点的左节点是否为空,如果不为空,则递归前序查找
        HeroNode resNode = null;
        if(this.left != null){
            resNode = this.left.preOrderSearch(no);
        }
        if(resNode != null){//说明左子节点上找到了
            return resNode;
        }
        if(this.right != null){
            resNode = this.right.preOrderSearch(no);
        }
            return resNode;
    }

    //中序遍历
    /**
     *
     * @param no  查找的no
     * @return    返回查找的节点
     */

    public HeroNode infixOrderSearch(int no){
        //判断当前节点的左子节点是否为空,如果不为空,则递归中序查找
        HeroNode resNode = null;
        if(this.left != null){
            resNode = this.left.infixOrderSearch(no);
        }
        if(resNode != null){
            return resNode;
        }
        //如果左边没有找到,则比较当前节点。如果是,就返回当前节点
        if(this.no == no){
            return this;
        }
        //否则向右进行中序查找
        if(this.right != null){
            resNode = this.right.infixOrderSearch(no);
        }
        return resNode;
    }

    //前序查找

    /**
     *
     * @param no  需要找的节点
     * @return
     */
    public HeroNode postOrderSearch(int no){
        //判断当前节点的左子节点是否为空,如果不为空,则递归后序查找
        HeroNode resNode = null;
        if(this.left != null){
            resNode = this.left.postOrderSearch(no);
        }
        if(resNode != null){
            return resNode;
        }
        if(this.right != null){
            resNode = this.right.postOrderSearch(no);
        }
        if(resNode != null){
            return resNode;
        }
        if(this.no == no){
            return this;
        }
        return resNode;

    }

}



删除代码


  • 考虑树如果是空树root,如果只有一个root节点,则等价于将二叉树置空。

  • (1). 因为我们的二叉树是单向的,所以我们需要判断当前节点的子节点是否需要删除节点。而不是考虑 删除当前节点。

  • (2). 如果当前节点的左子节点不为空,并且左子节点的编号就是需要删除的节点,this.left = null;并且就返回(结束递归删除)。

  • (3). 如果当前节点的右子节点不为空,并且右子节点的编号就是需要删除的节点,ths.right = null; 并且就返回(结束递归删除)。

  • (4). 如果第2和第3步没有删除节点,那么我们就需要向左子树进行递归删除

  • (5). 如果第4步没有删除节点,那么我们就需要向右子树进行递归删除

//完成删除操作
//规定:
//		(1). 如果删除的节点是叶子节点,则删除该节点
//		(2). 如果删除的是非叶子节点,则删除该子树

//思路:

//		考虑树如果是空树root,如果只有一个root节点,则等价于将二叉树置空。

//	***	(1). 因为我们的二叉树是单向的,所以我们需要判断当前节点的子节点是否需要删除节点。而不是考虑
//			 删除当前节点。

//		(2). 如果当前节点的左子节点不为空,并且左子节点的编号就是需要删除的节点,this.left = null;
//			 并且就返回(结束递归删除)。

//		(3). 如果当前节点的右子节点不为空,并且右子节点的编号就是需要删除的节点,ths.right = null;
//			 并且就返回(结束递归删除)。

//		(4). 如果第2和第3步没有删除节点,那么我们就需要向左子树进行递归删除

//		(5). 如果第4步没有删除节点,那么我们就需要向右子树进行递归删除



package Package01;

public class BinaryTree {
    public static void main(String[] args) {

        //先需要创建一棵二叉树
        BinaryTreee binaryTreee = new BinaryTreee();
        HeroNode root = new HeroNode(1,"宋江");
        HeroNode node2 = new HeroNode(2,"吴用");
        HeroNode node3 = new HeroNode(3,"卢俊义");
        HeroNode node4 = new HeroNode(4,"林冲");
        HeroNode node5 = new HeroNode(5,"关胜");


        //我们先手动创建二叉树,后面再使用递归创建二叉树
        root.setLeft(node2);
        root.setRight(node3);
        node3.setRight(node4);
        node3.setLeft(node5);
        binaryTreee.setRoot(root);


        //测试遍历
        System.out.println("++++++++++ 测试遍历 ++++++++++");
        System.out.println();
        System.out.println("前序遍历:" );
        binaryTreee.preOrder();
        System.out.println("中序遍历:" );
        binaryTreee.infixOrder();
        System.out.println("后序遍历:" );
        binaryTreee.postOrder();


        //测试查找
        System.out.println();
        System.out.println("++++++++++ 测试查找 ++++++++++");
        System.out.println();
        System.out.println("前序查找:");
        HeroNode resNode = binaryTreee.preOrderSearch(4);
        if(resNode != null){
            System.out.printf("找到了,信息为no=%d name=%s",resNode.getNo(),resNode.getName());
        }else{
            System.out.printf("没有找到no = %d 的英雄",4);
        }


        //删除节点
        System.out.println();
        System.out.println();
        System.out.println("++++++++++ 测试删除 ++++++++++");
        System.out.println();
        System.out.println("删除前,前序遍历:");
        binaryTreee.preOrder();
        System.out.println("删除后,前序遍历");
        binaryTreee.delNode(5);
        binaryTreee.preOrder();




    }


}

//定义一个BinaryTree
class BinaryTreee{
    public HeroNode root;

    public void setRoot(HeroNode root) {
        this.root = root;
    }

    //**************************** 遍历 **************************
    //前序遍历
    public void preOrder(){
        if(this.root!=null){
            this.root.preOrder();
        }else{
            System.out.println("二叉树为空,无法遍历");
        }
    }
    //中序遍历
    public void infixOrder(){
        if(this.root!=null){
            this.root.infixOrder();
        }else{
            System.out.println("二叉树为空,无法遍历");
        }
    }
    //后序遍历
    public void postOrder(){
        if(this.root!=null){
            this.root.postOrder();
        }else{
            System.out.println("二叉树为空,无法遍历");
        }
    }

    //**************************** 查找 **************************

    //前序查找
    public HeroNode preOrderSearch(int no){
        if(root != null){
            return root.postOrderSearch(no);
        }else{
            return null;
        }
    }

    //中序查找
    public HeroNode infixOrderSearch(int no){
        if(root != null){
            return root.infixOrderSearch(no);
        }else{
            return null;
        }
    }

    //后序查找
    public HeroNode postOrsearSearch(int no){
        if(root != null){
            return root.infixOrderSearch(no);
        }else{
            return null;
        }
    }

    //**************************** 删除 **************************
    //删除节点的代码不一样,判断树是不是只有root节点(root 是否 为需要删除的节点),判断root空不空都是在BinaryTreee里面进行的。
    //删除节点的代码:root 是否 为需要删除的节点是放在BinaryTreee里面进行的。
    //而查找代码:   root 是否 是需要查找的节点是放在HeroNode类里面的
    //在节点里面的delNode函数,是指已经进入节点在查找删除里面的情况了。
    public void delNode(int no){
        if(root != null){
            if(root.getNo() == no){
                root = null;
            }else{
                //递归删除
                root.delNode(no);
            }

        }else{
            System.out.println("这是一个空树,无法删除");
        }

    }




}


//先创建HeroNode节点
class HeroNode{
    private int no;
    private String name;
    private HeroNode left;  //默认为nul,不需要写在构造函数里面
    private HeroNode right; //默认为null,不需要写在构造函数里面

    public HeroNode(int no, String name){
        super();
        this.no = no;
        this.name = name;
    }

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public HeroNode getLeft() {
        return left;
    }

    public void setLeft(HeroNode left) {
        this.left = left;
    }

    public HeroNode getRight() {
        return right;
    }

    public void setRight(HeroNode right) {
        this.right = right;
    }

    @Override
    public String toString() {
        return "HeroNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                '}';
    }


    //**************************** 遍历 **************************
    //编写前序遍历的方法
    public void preOrder(){
        System.out.println(this);   //先输出父节点
        //递归向左子树遍历
        if(this.left!=null){
            this.left.preOrder();
        }
        //递归向右子树
        if(this.right!=null){
            this.right.preOrder();
        }

    }

    //中序遍历
    public void infixOrder(){
        //首先递归向左子树
        if(this.left!=null){
            this.left.infixOrder();
        }
        //输出父节点
        System.out.println(this);
        //递归向右子树
        if(this.right!=null){
            this.right.infixOrder();
        }

    }

    //后序遍历
    public void postOrder(){
        //先遍历左子节点
        if(this.left!=null){
            this.left.postOrder();
        }
        //再遍历右子节点
        if(this.right!=null){
            this.right.postOrder();
        }
        //输出父节点
        System.out.println(this);

    }


    //**************************** 查找 **************************
    //前序遍历查找
    public HeroNode preOrderSearch(int no){
        //比较当前节点是不是no
        if(this.no==no){
            return this;
        }
        //如果不是,则判断当前节点的左节点是否为空,如果不为空,则递归前序查找
        HeroNode resNode = null;
        if(this.left != null){
            resNode = this.left.preOrderSearch(no);
        }
        if(resNode != null){//说明左子节点上找到了
            return resNode;
        }
        if(this.right != null){
            resNode = this.right.preOrderSearch(no);
        }
            return resNode;
    }

    //中序遍历
    public HeroNode infixOrderSearch(int no){
        //判断当前节点的左子节点是否为空,如果不为空,则递归中序查找
        HeroNode resNode = null;
        if(this.left != null){
            resNode = this.left.infixOrderSearch(no);
        }
        if(resNode != null){
            return resNode;
        }
        //如果左边没有找到,则比较当前节点。如果是,就返回当前节点
        if(this.no == no){
            return this;
        }
        //否则向右进行中序查找
        if(this.right != null){
            resNode = this.right.infixOrderSearch(no);
        }
        return resNode;
    }

    //前序查找
    public HeroNode postOrderSearch(int no){
        //判断当前节点的左子节点是否为空,如果不为空,则递归后序查找
        HeroNode resNode = null;
        if(this.left != null){
            resNode = this.left.postOrderSearch(no);
        }
        if(resNode != null){
            return resNode;
        }
        if(this.right != null){
            resNode = this.right.postOrderSearch(no);
        }
        if(resNode != null){
            return resNode;
        }
        if(this.no == no){
            return this;
        }
        return resNode;

    }


    //**************************** 删除 **************************


    // ***	(1). 因为我们的二叉树是单向的,所以我们需要判断当前节点的子节点是否需要删除节点。而不是考虑

    //			 删除当前节点。

    //		(2). 如果当前节点的左子节点不为空,并且左子节点的编号就是需要删除的节点,this.left = null;
    //			 并且就返回(结束递归删除)。

    //		(3). 如果当前节点的右子节点不为空,并且右子节点的编号就是需要删除的节点,ths.right = null;
    //			 并且就返回(结束递归删除)。

    //		(4). 如果第2和第3步没有删除节点,那么我们就需要向左子树进行递归删除

    // 		(5). 如果第4步没有删除节点,那么我们就需要向右子树进行递归删除

    public void delNode(int no){
        // 思路:
//        (2)如果当前节点的左子节点不为空,并且左子节点的编号就是需要删除的节点,this.left = null;
//           并且就返回(结束递归删除)。
        if(this.left != null && this.left.no == no){
            this.left = null;
            return;
        }
//        (3). 如果当前节点的右子节点不为空,并且右子节点的编号就是需要删除的节点,ths.right = null;
//             并且就返回(结束递归删除)。
        if(this.right != null && this.right.no==no){
            this.right = null;
            return;
        }
//        (4). 如果第2和第3步没有删除节点,那么我们就需要向左子树进行递归删除
        if(this.left != null){
            this.left.delNode(no);
        }
//        (5). 如果第4步没有删除节点,那么我们就需要向右子树进行递归删除
        if(this.right != null){
            this.right.delNode(no);
        }


    }


}




存储二叉树


顺序存储:

  • (1). 顺序二叉树通常只考虑完全二叉树
  • (2). 第n个元素的左子节点为 2 * n + 1
  • (3). 第n个元素的右子节点为 2 * n + 2
  • (4). 第n个元素的父亲节点为 (n-1) / 2
//顺序存储二叉树    ------>   数组 [0,1,2,3,4,......,n]
//(1). 顺序二叉树通常只考虑完全二叉树
//(2). 第n个元素的左子节点为 2*n + 1
//(3). 第n个元素的右子节点为 2*n + 2
//(4). 第n个元素的父亲节点为 (n-1)/2

//需求:给你一个数组 {1,2,3,4,5,6,7},要求以二叉树前序遍历的方式进行遍历。
//前序遍历的结果应当为:  1,2,4,5,3,6,7



package Package01;

public class ArrBinaryTreeDemo {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5,6,7};
        //创建一个ArrBinaryTree对象
        ArrBinaryTree arrBinaryTree = new ArrBinaryTree(arr);
        arrBinaryTree.preOrder();      // 1,2,4,5,3,6,7

    }
}



//编写一个ArrayBinaryTree,实现顺序存储二叉树的遍历
class ArrBinaryTree{
    private int[] arr;  //存储数据节点的数组

    public ArrBinaryTree(int[] arr){
        this.arr = arr;
    }

    //重载preOrder(),这样代码看起来会简洁一些
    public void preOrder(){
        this.preOrder(0);
    }


    //编写一个方法,完成顺序存储二叉树的前序遍历
    public void preOrder(int index){
        //如果数组为空,或者arr.length = 0;
        if(arr == null || arr.length == 0){
            System.out.println("数组为空,不能按照二叉树的前序遍历");
        }
        //输出当前这个元素
        System.out.println(arr[index]);
        //向左前序遍历
        if((index * 2 +1 < arr.length)){
            preOrder(2 * index + 1);
        }
        //向右递归
        if(index * 2 + 1 < arr.length){
            preOrder(2 * index +2);
        }
    }

}



1.4 线索化二叉树

  • n 个节点的二叉链表中含有 n+1 [公式:2n - (n-1) = n+1] 个空指针域。利用二叉链表的空指针域,存放指向节点在某种遍历次序下的前驱和后继节点的指针 (这种附加的指针称为“线索”)。
  • 加上这种线索的二叉链表称为线索链表,相应的二叉树称为线索二叉树(Threaded BinaryTree)。根据线索性质的不同,线索二叉树可以分为前序线索二叉树中序线索二叉树后续线索二叉树三种。
  • 一个结点的前一个节点,称为前驱节点。
  • 一个结点的后一个节点,称为后继节点。

2.堆排序


  • 将待排序列构造成一个大顶堆 {大顶堆是通过树结构的方式构建一个数组}
  • 此时,整个序列的最大值就是堆顶的根节点
  • 将其与末尾元素进行交换,此时末尾就为最大值 {将最大值放在末尾,前面的n-1个为次小值}
  • 将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便可以得到一个有序序列了。

3.赫夫曼树

  • 给定n个权值作为n个叶子节点,构造一个二叉树,如果该数的带权路经长度(wql)达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree),还有的书翻译为霍夫曼树。

  • 赫夫曼树是带权路径长度最短的树,权值较大的节点离根较近。

  • 赫夫曼树的构建步骤:

    • 1.从小到大进行排序,将每一个数据,每一个数据可以看成每一个节点,每一个节点都是一颗最简单的二叉树
    • 2.取出根节点权值最下的两颗二叉树
    • 3.组成一颗新的二叉树,该二叉树的根节点的权值是前面两颗二叉树根节点权值的和
    • 4.再将这颗新的二叉树,以根节点的权值大小再次排序,不断重复1-2-3-4步骤,直到数列中,所有的数据都被处理,就得到一个赫夫曼树。
  • 赫夫曼编码基本介绍:

    • 赫夫曼编码也翻译为霍夫曼编码,是一种编码方式,属于一种程序算法
    • 赫夫曼编码是赫夫曼树在通信中的经典应用
    • 赫夫曼编码广泛的用于数据文件的压缩。其压缩率通常在20%-90%之间
    • 赫夫曼码是可变字长编码的一种

4.二叉排序树

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Martin__Liu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值