【数据结构-树】哈夫曼树

news2024/11/25 20:19:07

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。
img

  • 推荐:kuan 的首页,持续学习,不断总结,共同进步,活到老学到老
  • 导航
    • 檀越剑指大厂系列:全面总结 java 核心技术点,如集合,jvm,并发编程 redis,kafka,Spring,微服务,Netty 等
    • 常用开发工具系列:罗列常用的开发工具,如 IDEA,Mac,Alfred,electerm,Git,typora,apifox 等
    • 数据库系列:详细总结了常用数据库 mysql 技术点,以及工作中遇到的 mysql 问题等
    • 懒人运维系列:总结好用的命令,解放双手不香吗?能用一个命令完成绝不用两个操作
    • 数据结构与算法系列:总结数据结构和算法,不同类型针对性训练,提升编程思维,剑指大厂

非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。💝💝💝 ✨✨ 欢迎订阅本专栏 ✨✨

博客目录

    • 一.哈夫曼算法
      • 1.什么是编码?
      • 2.编码传输规则
      • 3.Huffman 编码
    • 二.哈夫曼树
      • 1.什么 Huffman 树?
      • 2.哈夫曼树特点
      • 3.节点总数证明
      • 4.Huffman 树特点
    • 三.常见方法
      • 1.内部 Node 节点
      • 2.构造方法
      • 3.编码
      • 4.解码
      • 5.完整代码
    • 四.练习题
      • 1.连接棒材的最低费用-力扣 1167 题

一.哈夫曼算法

1.什么是编码?

简单说就是建立【字符】到【数字】的对应关系,如下面大家熟知的 ASC II 编码表,例如,可以查表得知字符【a】对应的数字是十六进制数【0x61】

\000102030405060708090a0b0c0d0e0f
0000000102030405060708090a0b0c0d0e0f
0010101112131415161718191a1b1c1d1e1f
002020!"#$%&()*+,-./
00300123456789:;<=>?
0040@ABCDEFGHIJKLMNO
0050PQRSTUVWXYZ[\]^_
0060`abcdefghijklmno
0070pqrstuvwxyz{|}~7f

注:一些直接以十六进制数字标识的是那些不可打印字符

2.编码传输规则

传输时的编码

  • java 中每个 char 对应的数字会占用固定长度 2 个字节
  • 如果在传输中仍采用上述规则,传递 abbccccccc 这 10 个字符
    • 实际的字节为 0061006200620063006300630063006300630063(16 进制表示)
    • 总共 20 个字节,不经济

现在希望找到一种最节省字节的传输方式,怎么办?

假设传输的字符中只包含 a,b,c 这 3 个字符,有同学重新设计一张二进制编码表,见下图

  • 0 表示 a
  • 1 表示 b
  • 10 表示 c

现在还是传递 abbccccccc 这 10 个字符

  • 实际的字节为 01110101010101010 (二进制表示)
  • 总共需要 17 bits,也就是 2 个字节多一点,行不行?

不行,因为解码会出现问题,因为 10 会被错误的解码成 ba,而不是 c

  • 解码后结果为 abbbababababababa,是错误的

怎么解决?必须保证编码后的二进制数字,要能区分它们的前缀(prefix-free)

用满二叉树结构编码,可以确保前缀不重复

image-20230616094945068

  • 向左走 0,向右走 1
  • 走到叶子字符,累计起来的 0 和 1 就是该字符的二进制编码

再来试一遍

  • a 的编码 0
  • b 的编码 10
  • c 的编码 11

现在还是传递 abbccccccc 这 10 个字符

  • 实际的字节为 0101011111111111111(二进制表示)
  • 总共需要 19 bits,也是 2 个字节多一点,并且解码没有问题了,行不行?

这回解码没问题了,但并非最少字节,因为 c 的出现频率高(7 次)a 的出现频率低(1 次),因此出现频率高的字符编码成短数字更经济

3.Huffman 编码

考察下面的树

image-20230616095129461

  • 00 表示 a
  • 01 表示 b
  • 1 表示 c

现在还是传递 abbccccccc 这 10 个字符

  • 实际的字节为 000101 1111111 (二进制表示)
  • 总共需要 13 bits,这棵树就称之为 Huffman 树
  • 根据 Huffman 树对字符和数字进行编解码,就是 Huffman 编解码

二.哈夫曼树

1.什么 Huffman 树?

哈夫曼树,英文名 huffman tree,它是一种的叶子节点带有权重的特殊二叉树,也叫最优二叉树。

哈夫曼(Huffman)编码是上个世纪五十年代由哈夫曼教授研制开发的,它借助了数据结构当中的树型结构,在哈夫曼算法的支持下构造出一棵最优二叉树,我们把这类树命名为哈夫曼树。

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

2.哈夫曼树特点

哈夫曼树的特点:

  • 没有度为1的节点(每个非叶子节点都是由两个最小值的节点构成)

  • n 个叶子节点的哈夫曼树总共有2n-1个节点;

  • 哈夫曼树的任意非叶节点的左右子树交换后仍是哈夫曼树

  • 对同一组权值{w1,w2,…},存在不同构的两个哈夫曼树,但是它们的总权值相等。

  • 形成了这样的一颗哈夫曼树,这也是二叉树的前序

3.节点总数证明

证明哈夫曼树中有 n 个叶子节点的树总共有 2n-1 个节点可以使用数学归纳法。以下是证明的步骤:

步骤 1:基础情况
当 n=1 时,只有一个叶子节点,因此整棵哈夫曼树只有一个节点。这是一个基础情况。

步骤 2:归纳假设
假设对于某个正整数 k,当哈夫曼树有 k 个叶子节点时,它总共有 2k-1 个节点。

步骤 3:归纳证明
现在,考虑有 k+1 个叶子节点的情况。我们可以将这个问题分成两个部分:

部分 1: 从 k 个叶子节点构建一个哈夫曼树,根据归纳假设,这个树有 2k-1 个节点。

部分 2: 现在,我们添加一个额外的叶子节点,构建一个新的哈夫曼树。在这个新树中,我们需要添加一个新的内部节点,作为新叶子节点和部分 1 中的树的根节点的父节点。这个新树总共有 2k 个叶子节点和 1 个额外的内部节点,所以共有 2k+1 个节点。

现在,将部分 1 和部分 2 合并在一起,我们得到了有 k+1 个叶子节点的哈夫曼树,总共有(2k-1) + (2k+1) = 2k-1 + 2k+1 = 2(k-1+2) = 2k+1-1 个节点。

这证明了对于 k+1 个叶子节点的情况,有 2k+1-1 个节点,即当 n=k+1 时,也成立。

由于基础情况成立,并且我们已经证明了当 n=k+1 时成立,所以根据数学归纳法,对于所有正整数 n,有 n 个叶子节点的哈夫曼树总共有 2n-1 个节点。

4.Huffman 树特点

哈夫曼树(Huffman Tree)是一种用于数据压缩的树形数据结构,它具有以下几个特点:

  1. 最优编码:哈夫曼树被设计用来实现最优的数据压缩编码,这意味着它可以生成具有最小平均编码长度的编码方案,以便在数据传输或存储时能够节省空间。

  2. 基于频率:哈夫曼树的构建是基于数据中各个字符(或符号)的出现频率来进行的。频率高的字符被赋予较短的编码,而频率低的字符被赋予较长的编码。

  3. 唯一性:对于给定的数据集,存在唯一的哈夫曼树。这意味着如果两个人使用相同的数据集和相同的构建规则来创建哈夫曼树,它们将得到相同的树结构和编码。

  4. 前缀编码:哈夫曼编码是一种前缀编码,意味着没有一个字符的编码是另一个字符编码的前缀。这个特性确保在解码时不会产生歧义。

  5. 树形结构:哈夫曼树是一种二叉树,它由内部节点和叶子节点组成。叶子节点对应于数据集中的字符,而内部节点是用于构建编码的辅助节点。

  6. 压缩率:哈夫曼编码通常能够实现较高的压缩率,尤其是对于具有不同频率分布的数据集。频率高的字符使用较短的编码,从而实现更好的压缩效果。

  7. 动态性:哈夫曼编码可以动态地根据数据集的特性进行调整,以适应不同的数据。这使得它在各种应用中都具有灵活性。

总之,哈夫曼树是一种用于数据压缩的有效工具,其特点包括最优编码、基于频率、唯一性、前缀编码、树形结构、高压缩率和动态性。通过合理构建哈夫曼树,可以实现高效的数据压缩和解压缩操作。

三.常见方法

1.内部 Node 节点

/**
 * Node代表字符节点
 */
static class Node {
    /**
     * 字符
     */
    Character ch;
    /**
     * 频次
     */
    int freq;
    /**
     * 左子节点
     */
    Node left;
    /**
     * 右子节点
     */
    Node right;
    /**
     * 编码
     */
    String code;

    public Node(Character ch) {
        this.ch = ch;
    }

    public Node(int freq, Node left, Node right) {
        this.freq = freq;
        this.left = left;
        this.right = right;
    }

    int freq() {
        return freq;
    }

    boolean isLeaf() {
        return left == null;
    }

    @Override
    public String toString() {
        return "Node{" + "ch=" + ch + ", freq=" + freq + '}';
    }
}

2.构造方法

public HuffmanTree(String str) {
    this.str = str;
    // 功能1:统计字符的频率
    char[] chars = str.toCharArray();
    for (char c : chars) {
        Node node = map.computeIfAbsent(c, Node::new);
        node.freq++;
    }
    // 功能2: 构造树
    PriorityQueue<Node> queue = new PriorityQueue<>(Comparator.comparingInt(Node::freq));
    queue.addAll(map.values());
    while (queue.size() >= 2) {
        Node x = queue.poll();
        Node y = queue.poll();
        int freq = x.freq + y.freq;
        queue.offer(new Node(freq, x, y));
    }
    root = queue.poll();
    // 功能3:计算每个字符的编码,
    int sum = dfs(root, new StringBuilder());
    for (Node node : map.values()) {
        System.out.println(node + " " + node.code);
    }
    // 功能4:字符串编码后占用 bits
    System.out.println("总共会占用 bits:" + sum);
}

private int dfs(Node node, StringBuilder code) {
        int sum = 0;
        if (node.isLeaf()) {
            node.code = code.toString();
            sum = node.freq * code.length();
        } else {
            sum += dfs(node.left, code.append("0"));
            sum += dfs(node.right, code.append("1"));
        }
        if (code.length() > 0) {
            code.deleteCharAt(code.length() - 1);
        }
        return sum;
    }

3.编码

public String encode() {
    //abbccccccc
    char[] chars = str.toCharArray();
    StringBuilder sb = new StringBuilder();
    for (char c : chars) {
        sb.append(map.get(c).code);
    }
    return sb.toString();
}

4.解码

public String decode(String str) {
    /*
        从根节点,寻找数字对应的字符
            数字是 0 向左走
            数字是 1 向右走
            如果没走到头,每走一步数字的索引 i++
        走到头就可以找到解码字符,再将 node 重置为根节点
        a 00
        b 10
        c 1
                        i
        0   0   0   1   0   1   1   1   1   1   1   1   1
     */
    char[] chars = str.toCharArray();
    int i = 0;
    StringBuilder sb = new StringBuilder();
    Node node = root;
    //             i = 13  node=root
    // 0001011111111
    while (i < chars.length) {
        if (!node.isLeaf()) { // 非叶子
            if (chars[i] == '0') { // 向左走
                node = node.left;
            } else if (chars[i] == '1') { // 向右走
                node = node.right;
            }
            i++;
        }
        if (node.isLeaf()) {
            sb.append(node.ch);
            node = root;
        }
    }
    return sb.toString();
}

5.完整代码

/**
 * Huffman 树的构建过程
 * 1. 将统计了出现频率的字符,放入优先级队列
 * 2. 每次出队两个频次最低的元素,给它俩找个爹
 * 3. 把爹重新放入队列,重复 2~3
 * 4. 当队列只剩一个元素时,Huffman 树构建完成
 *
 * @author : qinyingjie
 * @date : 2023/9/26
 */
public class HuffmanTree {
    /**
     * Node代表字符节点
     */
    static class Node {
        /**
         * 字符
         */
        Character ch;
        /**
         * 频次
         */
        int freq;
        /**
         * 左子节点
         */
        Node left;
        /**
         * 右子节点
         */
        Node right;
        /**
         * 编码
         */
        String code;

        public Node(Character ch) {
            this.ch = ch;
        }

        public Node(int freq, Node left, Node right) {
            this.freq = freq;
            this.left = left;
            this.right = right;
        }

        int freq() {
            return freq;
        }

        boolean isLeaf() {
            return left == null;
        }

        @Override
        public String toString() {
            return "Node{" + "ch=" + ch + ", freq=" + freq + '}';
        }
    }

    String str;
    /**
     * 统计字符数量,key是字符,value是节点
     */
    Map<Character, Node> map = new HashMap<>();
    /**
     * 根节点
     */
    Node root;

    public HuffmanTree(String str) {
        this.str = str;
        // 功能1:统计字符的频率
        char[] chars = str.toCharArray();
        for (char c : chars) {
            Node node = map.computeIfAbsent(c, Node::new);
            node.freq++;
        }
        // 功能2: 构造树
        PriorityQueue<Node> queue = new PriorityQueue<>(Comparator.comparingInt(Node::freq));
        queue.addAll(map.values());
        while (queue.size() >= 2) {
            Node x = queue.poll();
            Node y = queue.poll();
            int freq = x.freq + y.freq;
            queue.offer(new Node(freq, x, y));
        }
        root = queue.poll();
        // 功能3:计算每个字符的编码,
        int sum = dfs(root, new StringBuilder());
        for (Node node : map.values()) {
            System.out.println(node + " " + node.code);
        }
        // 功能4:字符串编码后占用 bits
        System.out.println("总共会占用 bits:" + sum);
    }

    private int dfs(Node node, StringBuilder code) {
        int sum = 0;
        if (node.isLeaf()) {
            node.code = code.toString();
            sum = node.freq * code.length();
        } else {
            sum += dfs(node.left, code.append("0"));
            sum += dfs(node.right, code.append("1"));
        }
        if (code.length() > 0) {
            code.deleteCharAt(code.length() - 1);
        }
        return sum;
    }

    // 编码
    public String encode() {
        //abbccccccc
        char[] chars = str.toCharArray();
        StringBuilder sb = new StringBuilder();
        for (char c : chars) {
            sb.append(map.get(c).code);
        }
        return sb.toString();
    }

    // 解码
    public String decode(String str) {
        /*
            从根节点,寻找数字对应的字符
                数字是 0 向左走
                数字是 1 向右走
                如果没走到头,每走一步数字的索引 i++
            走到头就可以找到解码字符,再将 node 重置为根节点
            a 00
            b 10
            c 1
                            i
            0   0   0   1   0   1   1   1   1   1   1   1   1
         */
        char[] chars = str.toCharArray();
        int i = 0;
        StringBuilder sb = new StringBuilder();
        Node node = root;
        //             i = 13  node=root
        // 0001011111111
        while (i < chars.length) {
            if (!node.isLeaf()) { // 非叶子
                if (chars[i] == '0') { // 向左走
                    node = node.left;
                } else if (chars[i] == '1') { // 向右走
                    node = node.right;
                }
                i++;
            }
            if (node.isLeaf()) {
                sb.append(node.ch);
                node = root;
            }
        }
        return sb.toString();
    }

    public static void main(String[] args) {
        HuffmanTree tree = new HuffmanTree("abbccccccc");
        String encoded = tree.encode();
        System.out.println(encoded);
        System.out.println(tree.decode(encoded));
    }
}

四.练习题

1.连接棒材的最低费用-力扣 1167 题

题目编号题目标题算法思路
1167(Plus 题目)连接棒材的最低费用Huffman 树、贪心

为了装修新房,你需要加工一些长度为正整数的棒材 sticks。

如果要将长度分别为 X 和 Y 的两根棒材连接在一起,你需要支付 X + Y 的费用。

由于施工需要,你必须将所有棒材连接成一根。

返回你把所有棒材 sticks 连成一根所需要的最低费用。注意你可以任意选择棒材连接的顺序。

示例 1:
输入:sticks = [2,4,3]
输出:14
解释:先将 2 和 3 连接成 5,花费 5;再将 5 和 4 连接成 9;总花费为 14。
示例 2:
输入:sticks = [1,8,3,5]
输出:30
提示:
1 <= sticks.length <= 10^4
1 <= sticks[i] <= 10^4

题解

/**
 * <h3>连接棒材的最低费用</h3>
 * <p>为了装修新房,你需要加工一些长度为正整数的棒材。如果要将长度分别为 X 和 Y 的两根棒材连接在一起,你需要支付 X + Y 的费用。 返回讲所有棒材连成一根所需要的最低费用。</p>
 */
public class Leetcode1167 {
    /*
        举例 棒材为 [1,8,3,5]

        如果以如下顺序连接(非最优)
        - 1+8=9
        - 9+3=12
        - 12+5=17
        总费用为 9+12+17=38

        如果以如下顺序连接(最优)
        - 1+3=4
        - 4+5=9
        - 8+9=17
        总费用为 4+9+17=30
     */
    int connectSticks(int[] sticks) {
        PriorityQueue<Integer> queue = new PriorityQueue<>();
        for (int stick : sticks) {
            queue.offer(stick);
        }

        int sum = 0;
        while (queue.size() >= 2) {
            Integer x = queue.poll();
            Integer y = queue.poll();
            int c = x + y;
            sum += c;
            queue.offer(c);
        }
        return sum;
    }

    public static void main(String[] args) {
        Leetcode1167 leetcode = new Leetcode1167();
        System.out.println(leetcode.connectSticks(new int[]{1, 8, 3, 5})); // 30
        System.out.println(leetcode.connectSticks(new int[]{2, 4, 3})); // 14
    }
}

觉得有用的话点个赞 👍🏻 呗。
❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄

💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍

🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙

img

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1042920.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

transformer系列3---transformer结构参数量统计

Transformer参数量统计 1 Embedding2 Positional Encoding3 Transformer Encoder3.1 单层EncoderLayer3.1.1 MHA3.1.2 layer normalization3.1.3 MLP3.1.4 layer normalization 3.2 N层Encoderlayer总参数量 4 Transformer Decoder4.1 单层Decoderlayer4.1.1 mask MHA4.1.2 lay…

AUTOSAR中的Crypto Stack(二)--CSM数据类型解析

在上一节,简单梳理了加密栈的基本要求。其中最关键最核心的还是用户如何使用HSM这个黑盒子,这就必须要对Crypto Service Manager要有很清晰的认识。 那么首先我们还是围绕概述里提到的job类型进行分析。 1. Crypto_JobType 上图, 在AUTOSAR的架构里,所有的密码操作…

笔记本电脑查询连接wifi密码

笔记本电脑查询连接wifi密码 1、背景2、环境3、实操3.1、已连接wifi查看密码3.2、之前连接过的wifi密码查看 1、背景 在日常使用过程中遇到两个使用场景。网络管理员跳过一下步骤&#xff0c;针对wifi使用人员。 1、刚到一个新环境中需要连接wifi的场景 2、在一个场所连接过一…

【LeetCode热题100】--160.相交链表

160.相交链表 使用双指针&#xff1a; /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) {* val x;* next null;* }* }*/ public class Solution {public ListNode getInter…

基于Vue+ELement搭建动态树与数据表格实现分页

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《ELement》。&#x1f3af;&#x1f3af; &#x1…

高等数学应试考点速览(下)

函数项级数 【收敛域】上&#xff0c;收敛于&#xff1a;【和函数】&#xff1b; 幂级数&#xff1a;绝对收敛区间 ( − R , R ) (-R,R) (−R,R)&#xff0c;&#xff08;端点是否属于收敛域&#xff0c;需要再探讨&#xff09; R lim ⁡ n → ∞ ∣ a n a n 1 ∣ R\lim_{n…

LLM(二)| LIMA:在1k高质量数据上微调LLaMA1-65B,性能超越ChatGPT

本文将介绍在Lit-GPT上使用LoRA微调LLaMA模型&#xff0c;并介绍如何自定义数据集进行微调其他开源LLM 监督指令微调&#xff08;Supervised Instruction Finetuning&#xff09; 什么是监督指令微调&#xff1f;为什么关注它&#xff1f; 目前大部分LLM都是decoder-only&…

右键菜单添加 Open Git Bash

前言 在使用 TortoiseGit 作为Git的可视化工具&#xff0c;但是会经常用到命令行操作&#xff0c;一般来说&#xff0c;安装了TortoiseGit后&#xff0c;右键会出现 open git-bash here... 的命令。但是&#xff0c;可能由于某些原因&#xff0c;这个右键菜单选项不见了。下面…

springcloud:三、ribbon负载均衡原理+调整策略+饥饿加载

Ribbon负载均衡原理 调整Ribbon负载均衡策略 第一种会对order-service里所有的服务消费者都采用该新规则 第二种会针对order-service里某个具体的服务消费者采用该新规则 饥饿加载

【LeetCode】力扣364.周赛题解

Halo&#xff0c;这里是Ppeua。平时主要更新C&#xff0c;数据结构算法&#xff0c;Linux与ROS…感兴趣就关注我bua&#xff01; 1.最大二进制奇数 &#x1f349;题目&#xff1a; &#x1f349;例子&#xff1a; &#x1f349; 题解: 首先看题目,最大二进制奇数,在一个二…

二十六、MySQL并发事务问题:脏读/不可重复读/幻读

1、事务的隔离级别 &#xff08;1&#xff09;隔离级别 Read uncommitted # 读&#xff0c;未提交 Read committed # 读&#xff0c;已提交 Repeatable Read(默认) # 可重复读 Serializable # 串读 &#xff08;2&#xff09;基础语法 set transaction isolation level 事…

高等数学应试考点速览(上)

极限 上界存在&#xff0c;则上确界存在数列极限 定义性质&#xff1a;唯一、有界&#xff08;保序、夹逼、不等式性质&#xff09;、保号、四则运算判定&#xff1a; 单侧&#xff1a;单调有界双侧&#xff1a;闭区间套增量&#xff1a;柯西审敛 归并和收敛子列聚点有限覆盖原…

想要精通算法和SQL的成长之路 - 最长递增子序列 II(线段树的运用)

想要精通算法和SQL的成长之路 - 最长递增子序列 II&#xff08;线段树的运用&#xff09; 前言一. 最长递增子序列 II1.1 向下递推1.2 向上递推1.3 更新操作1.4 查询操作1.5 完整代码&#xff1a; 前言 想要精通算法和SQL的成长之路 - 系列导航 一. 最长递增子序列 II 原题链接…

idea 通过tomcat 配置 https方式访问

步骤1&#xff1a;管理员模式打开cmd命令进行生成密匙 D:\software\apache-tomcat-8.5.93\bin\tomcat.keystore 是生成密匙存放的路径&#xff0c;修改成自己tomcat的路径即可 keytool -genkeypair -alias "tomcat" -keyalg "RSA" -keystore "D:\s…

Spring Boot 集成 MinIO 实现文件上传、下载和删除

MinIO 是一种开源的对象存储服务&#xff0c;它基于云原生架构构建&#xff0c;并提供了高性能、易于扩展和安全的存储解决方案。 一.安装和配置 MinIO 服务器 为了演示方便&#xff0c;本文采用Windows安装 1.在官方网站下载MinIO 安装文件&#xff0c;地址&#xff1a;ht…

MATLAB中norm函数用法

目录 语法 说明 示例 向量模 向量的 1-范数 两个点之间的欧几里德距离 矩阵的 2-范数 N 维数组的 Frobenius 范数 常规向量范数 norm函数的功能是计算向量范数和矩阵范数。 语法 n norm(v) n norm(v,p) n norm(X) n norm(X,p) n norm(X,"fro") 说明…

Android 面试经历复盘整理~

此次面试一共4面4小时&#xff0c;中间只有几分钟间隔。对持续的面试状态考验还是蛮大的。 关于面试的心态&#xff0c;保持悲观的乐观主义心态比较好。面前做面试准备时保持悲观&#xff0c;尽可能的做足准备。面后积极做复盘&#xff0c;乐观的接受最终结果。 切忌急于下结论…

从裸机开始安装操作系统

目录 一、预置知识 电脑裸机 win10版本 官方镜像 V.S. 正版系统 二、下载微软官方原版系统镜像 三、使用微PE系统维护U盘 四、安装操作系统 五、总结 一、预置知识 电脑裸机 ●只有硬件部分&#xff0c;还未安装任何软件系统的电脑叫做裸机。 ●主板、硬盘、显卡等必…

2005-2018年上市公司高管前三名薪酬比例数据

2005-2018年上市公司高管前三名薪酬比例数据 1、时间&#xff1a;2005-2018年 2、指标&#xff1a;证券代码、year、高管薪酬总额、高管前三名薪酬总额、高管前三名薪酬比例、市场类型、行业代码、交易状态 3、范围&#xff1a;上市公司 4、指标解释&#xff1a; 薪酬是员…

深入理解C语言(1):数据在内存中的存储

文章主题&#xff1a;数据在内存中的存储&#x1f30f;所属专栏&#xff1a;深入理解C语言&#x1f4d4;作者简介&#xff1a;更新有关深入理解C语言知识的博主一枚&#xff0c;记录分享自己对C语言的深入解读。&#x1f606;个人主页&#xff1a;[₽]的个人主页&#x1f3c4;&…