数据结构之二叉树及面试题讲解

 💕"从前种种譬如昨日死;从后种种譬如今日生"💕

作者:Mylvzi 

 文章主要内容:数据结构之二叉树及面试题讲解 

一.概念

1.树的定义

  树是一种非线性的数据结构,是由n个结点组成的一种非线性集合;之所以叫做树,是因为他看起来像一颗倒挂的树,也就是根朝上,叶子朝下,一颗二叉树具有以下特征

  • 有一个特殊节点--根节点  一颗二叉树有且仅有一个根节点
  • 树是递归定义的

2.树与非树

  如何判断一棵树是否是树呢?可以通过以下几个方式

  • 除根节点外,其余结点有且仅有一个父节点
  • 一棵树如果有n个结点,则一定有n-1条边
  • 子树是不相交的

3.树的相关概念

  • 度:某个结点的子结点个数就叫做该节点的度  比如B结点的度就是2,因为其有两个子节点
  • 树的度:指的是结点度的最大值   如图A结点的度是3,所以树的度就是3
  • 叶子节点(终端节点):没有子节点的结点  比如E,F,G
  • 祖先节点:所有节点的父节点  就是根节点  本图中A结点时祖先节点
  • 父节点:结点的前驱结点就是父节点,也叫做双亲结点  B是E,F的父节点
  • 孩子节点:与父结点相对
  • 树的高度:树的层次的最大值就是树的高度  如图层次是三,所以树的高度就是3
  • 树的以下概念只需了解,在看书时只要知道是什么意思即可:
  • 非终端结点或分支结点:度不为0的结点; 
  • 兄弟结点:具有相同父结点的结点互称为兄弟结点;
  • 堂兄弟结点:双亲在同一层的结点互为堂兄弟;
  • 森林:由m(m>=0)棵互不相交的树组成的集合称为森林

4.树的表示形式(了解)

树结构相对线性表就比较复杂了,要存储表示起来就比较麻烦了,实际中树有很多种表示方式,如:双亲表示法, 孩子表示法、孩子双亲表示法、孩子兄弟表示法等等。我们这里就简单的了解其中最常用的孩子兄弟表示法。

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

二. 二叉树(重点) 

1.概念

  二叉树是树形结构的一种,二叉树就是度<= 2的的树

 二叉树是由以下几种情况组成

2.两种特殊的二叉树

  1.  满二叉树: 一棵二叉树,如果每层的结点数都达到最大值,则这棵二叉树就是满二叉树。也就是说,如果一棵 二叉树的层数为K,且结点总数是 2^k - 1,则它就是满二叉树。
  2.  完全二叉树: 完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的。对于深度为K的,有n 个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从0至n-1的结点一一对应时称之为完 全二叉树。 要注意的是满二叉树是一种特殊的完全二叉树。
  3. 完全二叉树就是从上到下,从左到右依次存放结点的树

3.二叉树的性质(重点 )

  • 若规定根结点的层数为1,则一棵非空二叉树的第i层上最多有(2^i - 1) (i>0)个结点
  • 若规定只有根结点的二叉树的深度为1,则深度为K的二叉树的最大结点数是(2^k - 1) (k>=0)推导:等比数列的求和公式推导而成
  • 具有n个结点的完全二叉树的深度k 为 Log(n+1)向 上取整
  • 对任何一棵二叉树, 如果其叶结点个数为 n0, 度为2的非叶结点个数为 n2,则有n0=n2+1  也就是叶子节点的个数一定比度为2的结点的个数多一

这个性质经常作为考试题目,会结合结点数目的奇偶性以及完全二叉树来出题

如果结点数是2N,则n1的个数一定是1

如果结点数是2N+1,则n1的个数一定是0

4.二叉树的存储

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

  顺序存储的底层其实是"堆"这种数据结构的实现,也就是二叉搜索树

  我们以链式的存储结构进行讲解

二叉树的链式存储结构是通过一个一个结点实现的,最常用的表示方法是左右孩子表示法,即每个节点存储左右孩子结点

定义结点内部类

static class TreeNode {public int val;public TreeNode lChild;// 左孩子public TreeNode rChild;// 右孩子public TreeNode(char val) {this.val = val;}}

手动插入结点

    public TreeNode create() {TreeNode A = new TreeNode('A');TreeNode B = new TreeNode('B');TreeNode C = new TreeNode('C');TreeNode D = new TreeNode('D');TreeNode E = new TreeNode('E');TreeNode F = new TreeNode('F');TreeNode G = new TreeNode('G');TreeNode H = new TreeNode('H');A.lChild = B;A.rChild = C;B.lChild = D;B.rChild = E;C.lChild = F;C.rChild = G;E.rChild = H;return A;}

2.二叉树的遍历

  遍历是二叉树的一个很重要的操作,二叉树作为一种存储数据的结构,在我们获取数据的时候需要遍历整棵二叉树,直到拿到我们所需要的数据,不同的遍历方式也会带来不同的效率,二叉树常见的遍历方式有:

  • 前序遍历preOrder  根左右
  • 中序遍历inOrder  左根右
  • 后序遍历postOrder 左右根
  • 层序遍历levelOrder 从上至下从左至右依次遍历每一个结点

遍历操作最核心的思路就是"子问题思路"和递归的思想,下面进行遍历的代码实现

把整棵二叉树想象为只有一个根节点和两个孩子节点的树,很多二叉树的问题就容易解决

要谨记,二叉树有两种,空树和非空树,任何情况下都不要忘记空树的情况

1,前序遍历

    // 前序public void preOrder(TreeNode root) {// 空树直接返回if(root == null) return;System.out.print(root.val+" ");// 打印完根节点再去访问左孩子和右孩子preOrder(root.lChild);preOrder(root.rChild);}

力扣题目 

https://leetcode.cn/problems/binary-tree-preorder-traversal/submissions/

代码实现

public List<Integer> preorderTraversal(TreeNode root) {List<Integer> list = new ArrayList<>();// 空树直接返回if(root == null) return list;list.add(root.val);// 遍历左子树List<Integer> leftTree = preorderTraversal(root.left);list.addAll(leftTree);// 遍历右子树List<Integer> rightTree = preorderTraversal(root.right);list.addAll(rightTree);return list;}

2.中序遍历

    // 中序public void inOrder(TreeNode root) {
// 空树 直接返回if(root == null) return;inOrder(root.lChild);System.out.print(root.val+" ");inOrder(root.rChild);}

https://leetcode.cn/problems/binary-tree-inorder-traversal/submissions/

代码实现

    public List<Integer> inorderTraversal(TreeNode root) {List<Integer> list = new ArrayList<>();// 空树 直接返回if(root == null) return list;// 遍历左子树List<Integer> leftTree = inorderTraversal(root.left);list.addAll(leftTree);list.add(root.val);// 遍历右子树List<Integer> rightTree = inorderTraversal(root.right);list.addAll(rightTree);return list;}

3,后序遍历

    public void postOrder(TreeNode root) {
// 空树 直接返回if(root == null) return;postOrder(root.lChild);postOrder(root.rChild);System.out.print(root.val+" ");}

https://leetcode.cn/problems/binary-tree-preorder-traversal/submissions/

代码实现

    public List<Integer> postorderTraversal(TreeNode root) {List<Integer> list = new ArrayList<>();if(root == null) return list;// 遍历左子树List<Integer> leftTree = postorderTraversal(root.left);list.addAll(leftTree);// 遍历右子树List<Integer> rightTree = postorderTraversal(root.right);list.addAll(rightTree);list.add(root.val);return list;}

4.层序遍历

  使用队列来模拟实现(自己画图想一下,很简单)

    /*** 层序遍历  一层一层的遍历  打印* 先遇到  先打印  fifo  先进先出  使用队列存储遍历的结点* @param root*/// 层序遍历public void levelOrder(TreeNode root) {if(root == null) return;Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);while(!queue.isEmpty()) {TreeNode cur = queue.poll();System.out.print(cur.val+" ");if (cur.lChild != null) {queue.offer(cur.lChild);}if (cur.rChild != null) {queue.offer(cur.rChild);}}}

https://leetcode.cn/problems/binary-tree-level-order-traversal/submissions/

    public List<List<Integer>> levelOrder(TreeNode root) {List<List<Integer>> ret = new ArrayList<>();if(root == null) return ret;Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);while(!queue.isEmpty()) {List<Integer> tmpList = new ArrayList<>();// 记录当前队列中的结点个数  决定了当前层的tmpList存储的结点个数  也方便添加后序的孩子节点int size = queue.size();while(size > 0) {TreeNode cur = queue.poll();if(cur.left != null) queue.offer(cur.left);if(cur.right != null) queue.offer(cur.right);tmpList.add(cur.val);size--;}ret.add(tmpList);}return ret;}

3.二叉树的基本操作 

5.求结点个数  

  最基本的思路就是定义一个计数器,遍历每一个结点,遍历的方法可以是前序,中序,后序,层序,下面实现两种:递归实现和子问题思路

注:这里的递归实现采用了前序遍历的方式

    /*** 求size  遍历每一个结点 设置一个计数器*/public int size = 0;public int getSize(TreeNode root) {
// 空树 直接返回  结点数为1if(root == null) return 0;size++;getSize(root.lChild);getSize(root.rChild);return size;}// 子问题思路:结点的个数 == 左子树的节点个数+右子树的结点个数+根节点public int getSize2(TreeNode root) {if(root == null) return 0;return getSize2(root.lChild) +getSize2(root.rChild) + 1;}

6.求叶子节点的个数

  叶子节点即左右孩子都为空的结点,要求叶子节点的个数,需要遍历寻找;

 /*** 求叶子节点的个数* 1.遍历实现  满足左右节点都为空  ++* 2.子问题思路:root叶子节点的个数 == 左子树叶子节点的个数+右子树叶子节点的个数*/public int leafSize = 0;public int getLeafSize(TreeNode root) {// 递归结束条件  这其实是二叉树的一种情况// 二叉树有两类  空树  和非空树// 空树 没有叶子结点  返回0if(root == null) return 0;if (root.lChild == null && root.rChild == null) {leafSize++;}getLeafSize(root.lChild);getLeafSize(root.rChild);return leafSize;}public int getLeafSize2(TreeNode root) {// 子问题思路// root叶子节点的个数 == 左子树叶子节点的个数+右子树叶子节点的个数if(root == null) return 0;if(root.lChild == null && root.rChild == null) return 1;return getLeafSize2(root.lChild) + getLeafSize2(root.rChild);}

 7.求第k层的结点个数

  转化为子问题思路

    /*** 获取第k层结点的个数* 子问题思路:等价于左树第k-1层和右树第k-1层结点的个数* 一直走到第k层* @param root* @param k* @return*/public int getKLevelNodeConut(TreeNode root,int k) {if(root == null) return 0;// 等于1  证明走到了第k层  现在就是第k层的某一个节点if(k == 1) return 1;return getKLevelNodeConut(root.lChild,k-1) +getKLevelNodeConut(root.rChild,k-1);}

 8.求树的高度

 子问题思路:树的高度 = 左树和右树高度的最大值+1

    // 这种方法可以通过  递归只计算了一次public int getHeight(TreeNode root) {// 想好递归条件  最后一定是走到null结点  其高度为0  往回归if(root == null) return 0;int leftHeight = getHeight(root.lChild);int rightHeight = getHeight(root.rChild);return leftHeight > rightHeight ? leftHeight+1 : rightHeight+1;}

 9.判断是否包含某节点

  先判断根节点  再去遍历左子树  左子树包含 直接返回  不包含   遍历右子树

    /*** 判断是否含有某个值的结点*/public boolean find(TreeNode root,char val) {// 为空  直接返回if(root == null) return false;if(root.val == val) return true;// 遍历左子树  如果找到,则flg1为true  直接返回即可  不需要再去遍历右子树boolean flg1 = find(root.lChild,val);if(flg1) return true;// 遍历右子树boolean flg2 = find(root.rChild,val);if(flg2) return true;return false;}

10.判断是否是完全二叉树

  利用层序遍历的思路,把当前结点的所有孩子结点都加入(如果孩子节点是null也会被插入),当遇到null时,如果是完全二叉树,则此结点一定是最后一个节点,即queue.size == 0,如果不是完全二叉树,则queue.size != 0

    /*** 判断是否是完全二叉树* 层序遍历的思路  把所有结点的左右孩子节点都存入到queue中  如果遇到null 去判断是否还存在元素* 存在 -- 不是完全二叉树* @param root* @return*/public boolean iscompleteTree(TreeNode root) {if(root == null) return true;Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);while (!queue.isEmpty()) {TreeNode cur = queue.poll();// 如果queue中存储的是null 它会被存储到queue中  但却不算有效数据个数if (cur == null) {if(queue.size() != 0) {return false;}}queue.offer(cur.lChild);queue.offer(cur.rChild);}return true;}

三.二叉树的相关OJ题目

  二叉树作为面试中常考的题目有一定的难度(且难度不小),需要认真去练习,总结

1.判断两棵树是否相同

https://leetcode.cn/problems/same-tree/submissions/

思路分析:
  这题可以采用子问题思路  先分析判断的思路,先判断结构上是否一致,如果一致,再去判断值是否相同

  • 如果一个为空,一个不为空,结构上不同  返回false
  • 如果两个都为空  返回true
  • 如果结构上完全相同,去判断值是否相同

代码实现

// 先判断当前所在根是否相同  不同  判断左结点  再判断右节点// 不同  值不同  一个为空,一个不为空  // 相同  值相同  或者两个都为空// 一个为空,一个不为空  if(p != null && q == null || p == null && q != null) return false;// 两个都为空  认为相等if(p == null && q == null) return true;// 值不同  走到这里说明两个引用都不为空  只需判断值是否相同即可if(p.val != q.val) return false;return isSameTree(p.left,q.left) && isSameTree(p.right,q.right);

2.另一棵树的子树

  https://leetcode.cn/problems/subtree-of-another-tree/description/

思路分析

  • 先判断root是否是null,为空直接返回false
  • 判断当前根节点是否和subRoot是否是相同的树
  • 再去递归遍历root的左树和右数是否和subRoot是相同的树 

代码实现

class Solution {private boolean isSameTree(TreeNode p,TreeNode q) {if(p == null && q != null || p != null && q == null) return false;if(p == null && q == null) return true;if(p.val != q.val) return false;return isSameTree(p.left,q.left) && isSameTree(p.right,q.right);}public boolean isSubtree(TreeNode root, TreeNode subRoot) {if(root == null ) return false;// 判断当前节点是否满足条件if(isSameTree(root,subRoot)) return true;// 递归遍历左树和右树if(isSubtree(root.left,subRoot)) return true;if(isSubtree(root.right,subRoot)) return true;// 走到这里 说明以上情况都不满足 直接返回false;return false;}
}

3.翻转二叉树

思路分析

  还是利用子问题思路,交换root的左右子树,再去更新root,继续交换左右子树 

https://leetcode.cn/problems/invert-binary-tree/submissions/

代码实现

    public TreeNode invertTree(TreeNode root) {if(root == null) return root;// 交换TreeNode tmp = root.left;root.left = root.right;root.right = tmp;// 交换根节点的左子树和右子树invertTree(root.left);invertTree(root.right);return root;}

4.判断平衡二叉树

https://leetcode.cn/problems/balanced-binary-tree/submissions/

1.遍历每一个节点  判断其左右子树是否平衡  只要求出当前结点左右子树的高度即可  同时还要保证其余节点也平衡

    // 求树的高度private int getHeight(TreeNode root) {if(root == null) return 0;int leftHeight = getHeight(root.left);int rightHeight = getHeight(root.right);return leftHeight > rightHeight ? leftHeight+1 : rightHeight+1;}public boolean isBalanced(TreeNode root) {if(root == null) return true;int leftHeight = getHeight(root.left);int rightHeight = getHeight(root.right);// 高度平衡的条件 每颗结点都要高度平衡  即每颗结点的左右子树的高度差都要<=1return Math.abs(leftHeight-rightHeight) <= 1 &&isBalanced(root.left) &&isBalanced(root.right);}

第一种方法时间复杂度达到了0(N^2),究其原因,在于在计算高度的时候发生了重复计算,在你求完root当前的高度之后还需要再去判断其左右子树是否平衡,判断的时候还需要再去求一遍高度,导致时间复杂度过高,我们发现,在求第一次高度时,整个求高度的过程中已经发现了不平衡的现象,我们可以在返回高度的过程中就去判断是否是平衡的

2.第二种思路

    // 求树的高度private int getHeight(TreeNode root) {if(root == null) return 0;int leftHeight = getHeight(root.left);int rightHeight = getHeight(root.right);// 返回正常高度的条件if(leftHeight >= 0 && rightHeight >= 0 && Math.abs(leftHeight-rightHeight) <= 1) {return Math.max(leftHeight,rightHeight)+1;}else {return -1;}}public boolean isBalanced(TreeNode root) {if(root == null) return true;return getHeight(root) >= 0;}

  正常返回高度的条件是

  • 左树高度和右树高度的绝对值之差 <= 1
  • 左子树的高度符合条件  即左子树的高度不是-1
  • 右子树的高度符合条件  即右子树的高度不是-1 

  这道题曾经是字节面试出的一道题,第一种思路很容易想到,即通过求当前结点的左右子树的高度的绝对值之差来判断是否符合条件,同时还要满足当前结点的左子树和右子树也符合条件(这一点也容易忽视),但这种思路存在着重复计算的问题 ,时间复杂度过高;

  重复计算的是高度,那能不能在一次求高度的过程中就判断是否符合条件?答案是可以的,就是提供的第二种思路

  这种在过程中判断是否符合条件从而减少计算量的思路经常出现,也不容易实现,可以好好学习,总结一下

5.二叉树的遍历

https://www.nowcoder.com/practice/4b91205483694f449f94c179883c1fef?tpId=60&&tqId=29483&rp=1&ru=/activity/oj&qru=/ta/tsing-kaoyan/question-ranking

思路分析:

本题是根据前序遍历的方式去创建二叉树,本质上还是利用递归的方式去创建树

先创建当前的根节点,再去创建结点的左树,最后创建结点的右树 

代码实现

import java.util.Scanner;// 结点的信息需要自行创建
class TreeNode {char val;TreeNode left;TreeNode right;public TreeNode() {};public TreeNode(char val) {this.val = val;};}// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseString s = in.nextLine();// 获取创建树的根节点TreeNode root = createTree(s);// 中序遍历inOrder(root);}}public static int i = 0;// 根据前序遍历的结果创建一棵树public  static TreeNode createTree(String s) {TreeNode root = null;if(s.charAt(i) != '#') {// 不是#号,证明就是一个结点  实例化一个结点  i++  再去分别创建该节点的左树,右树root = new TreeNode(s.charAt(i));i++;root.left = createTree(s);root.right = createTree(s);}else {// 是#  直接i++i++;}// 递归到最后要把节点之间联系起来  所以返回rootreturn root;}// 中序遍历public  static void inOrder(TreeNode root) {if(root == null) return;inOrder(root.left);System.out.print(root.val + " ");inOrder(root.right);}
}

6.前序+中序构造二叉树

https://leetcode.cn/problems/construct-binary-tree-from-preorder-and-inorder-traversal/

代码实现

//*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/class Solution {public TreeNode buildTree(int[] preorder, int[] inorder) {return buildChildTree(preorder,inorder,0,inorder.length-1);}// 应该将pi设置为成员变量  否则在递归回退的过程中会重新返回值public int pi;public TreeNode buildChildTree(int[] preorder,int[] inorder,int beginIndex,int endIndex) {// 1.没有左树  或者没有右树if(beginIndex > endIndex) {return null;}// 2.创建根节点TreeNode root = new TreeNode(preorder[pi]);// 3.在中序遍历中找到根节点int rootIndex = find(inorder,beginIndex,endIndex,preorder[pi]);if(rootIndex == -1) return null;pi++;// 创建左子树root.left = buildChildTree(preorder,inorder,beginIndex,rootIndex-1);// 创建右子树root.right = buildChildTree(preorder,inorder,rootIndex+1,endIndex);return root;}private int find(int[] inorder,int beginIndex,int endIndex,int key) {for(int i = beginIndex; i <= endIndex; i++) {if(inorder[i] == key) {return i;}}// 没找到  返回-1return -1;}
}

7.后序+中序构造二叉树

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public int pi;public TreeNode buildTree(int[] inorder,int[] postorder) {pi = postorder.length-1;return buildChildTree(postorder,inorder,0,inorder.length-1);}public TreeNode buildChildTree(int[] postorder,int[] inorder,int beginIndex,int endIndex) {if(beginIndex > endIndex) {return null;}TreeNode root = new TreeNode(postorder[pi]);int rootIndex = find(inorder,beginIndex,endIndex,postorder[pi]);if(rootIndex == -1) return null;pi--;// 创建右子树root.right = buildChildTree(postorder,inorder,rootIndex+1,endIndex);// 创建左子树root.left = buildChildTree(postorder,inorder,beginIndex,rootIndex-1);return root;}private int find(int[] inorder,int beginIndex,int endIndex,int key) {for(int i = beginIndex; i <= endIndex; i++) {if(inorder[i] == key) {return i;}}// 没找到  返回-1return -1;}
}

总结:

前序/后序+中序都能构造出一棵二叉树,如果是前序+后序无法得到 

8.最近的公共祖先

http://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-tree/

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode(int x) { val = x; }* }*/
class Solution {public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {if (root == null) return null;Stack<TreeNode> stack1 = new Stack<>();Stack<TreeNode> stack2 = new Stack<>();getPath(root, p, stack1);getPath(root, q, stack2);int sizeP = stack1.size();int sizeQ = stack2.size();if (sizeP > sizeQ) {int size = sizeP - sizeQ;while (size != 0) {stack1.pop();size--;}} else {int size = sizeQ - sizeP;while (size != 0) {stack2.pop();size--;}}// 此时两个栈的长度一致while(!stack1.peek().equals(stack2.peek())) {stack1.pop();stack2.pop();}return stack1.peek();}/*** 难点在于如何获得p,q路径上的所有节点* 利用栈存放通过前序遍历遇到的每一个节点  判断结点的左右子树是否包含要寻找的结点*/private boolean getPath(TreeNode root, TreeNode node, Stack<TreeNode> stack) {if(root == null || node == null) return false;stack.push(root);if(root == node) return true;boolean flg1 = getPath(root.left,node,stack);if(flg1) {return true;}boolean flg2 = getPath(root.right,node,stack);if (flg2) {return true;}stack.pop();return false;}}

 /*** 找最近的公共祖先  三种情况* @param root* @param p* @param q* @return*/public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {if(root == null)  return null;if(root == p || root == q) return root;// 判断是在同一边还是两侧TreeNode leftTree = lowestCommonAncestor(root.lChild,p,q);TreeNode rightTree = lowestCommonAncestor(root.rChild,p,q);if(leftTree != null && rightTree != null) {// 都不为空 证明p,q在根节点的左右两侧  公共祖先只能是rootreturn root;} else if (leftTree != null) {return leftTree;}else {return rightTree;}}

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

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

相关文章

Vue3.0 所采用的 Composition Api 与 Vue2.x 使用的 Options Api 有什么不同?

面试官&#xff1a;Vue3.0 所采用的 Composition Api 与 Vue2.x 使用的 Options Api 有什么不同&#xff1f; 开始之前 Composition API 可以说是Vue3的最大特点&#xff0c;那么为什么要推出Composition Api&#xff0c;解决了什么问题&#xff1f; 通常使用Vue2开发的项目&…

交流插座电器漏电断路器的低功耗控制芯片D4140,内置桥式整流器漏电灵敏度可调,采用SOP8和DIP8 的封装形式

D4140 是一种用于交流插座电器漏电断路器的低功耗控制器。这些设备可以检测到接地的危险电流路径&#xff0c;例如设备掉进水中。在发生有害或致命的电击之前&#xff0c;断路器会断开线路。内置有整流桥&#xff0c;齐纳管稳压器&#xff0c;运算放大器&#xff0c;电流基准&a…

论文阅读——Loss odyssey in medical image segmentation

Loss odyssey in medical image segmentation github&#xff1a;https://github.com/JunMa11/SegLossOdyssey 这篇文章回顾了医学图像分割中的20种不同的损失函数&#xff0c;旨在回答&#xff1a;对于医学图像分割任务&#xff0c;我们应该选择哪种损失函数&#xff1f; 首…

倾斜摄影三维模型的根节点合并的优势分析

倾斜摄影三维模型的根节点合并的优势分析 根节点合并是倾斜摄影三维模型处理中的一项重要技术&#xff0c;它具有许多优势&#xff0c;可以显著提升模型数据的处理效率和渲染性能。在本文中&#xff0c;我们将对倾斜摄影三维模型的根节点合并的优势进行详细分析。 1、数据大小…

计算机毕业设计|基于SpringBoot+SSM+MyBatis框架的迷你仿天猫商城购物系统设计与实现

计算机毕业设计|基于SpringBootMyBatis框架的仿天猫商城购物系统设计与实现 迷你仿天猫商城是一个基于SpringBootSSMMyBatis框架的综合性B2C电商平台&#xff0c;需求设计主要参考天猫商城的购物流程&#xff1a;用户从注册开始&#xff0c;到完成登录&#xff0c;浏览商品&am…

家用小型洗衣机哪款性价比高?内衣洗衣机品牌推荐

近日&#xff0c;国内著名的电子商务平台公布了“内衣洗衣机产业趋势”的研究报告。该报告指出&#xff0c;由于消费者对生活质量的要求越来越高&#xff0c;内衣洗衣机的行业也有了长足的发展&#xff0c;特别是在今年以来&#xff0c;内衣洗衣机的销售额同比上涨了830%&#…

汽车音响静音检测电路芯片D3703F,6V~16V SOP8封装

D3703F 是一块汽车音响静 音检测电路。用于音 响系统检测在放音或快进/退时进行静音检测&#xff0c;电压范围: 6V~16V&#xff0c;信号检测和静音时间可通过外围电阻 、电容来改变。D3703F采用SOP8的封装形式封装 主要特点: 快进/退时也可进行静音 检测 信号检测…

小黄鸟(HTTPCanary)安装及Android高版本CA证书配置

小黄鸟&#xff08;HTTPCanary&#xff09;安装及Android高版本CA证书配置 HTTPCanary及CA证书安装 1.HTTPCanary下载2.导出CA证书3.安装CA证书 1.HTTPCanary下载 从下面链接下载安装HTTPCanary 链接: https://xiao6ming6.lanzouq.com/iQcB902w15pg 密码:4wby 2.导出CA证书 1.…

关于this和构造器的理解

1.类中的this关键字表示当前对象的引用。它可以被用于解决变量名冲突问题&#xff0c;或者在一个方法中调用类的另一个方法。如果在方法中没有明确指定要使用哪个变量&#xff0c;那么编译器就会默认使用this关键字来表示当前对象。 下面是一个输出this关键字的示例代码&#…

信息泄露威胁:日本科技巨头遭网络攻击,超40万条数据悬崖边缘!

11月27日下午&#xff0c;日本最主要通讯应用程序Line的运营商、日本LY公司发布公告称&#xff0c;有攻击者通过附属公司的NAVER Cloud系统访问了其内部服务器&#xff0c;可能泄露了数十万条包含用户、员工和业务合作伙伴在内的数据。 这一数据泄露事件发生在10月9日&#xff…

关于你对 Zookeeper 的理解

看看普通人和高手是如何回答这个问题的&#xff1f; 普通人 Zookeeper 是一种开放源码的分布式应用程序协调服务 是一个分布式的小文件存储系统 一般对开发者屏蔽分布式应用开发过过程种的底层细节 用来解决分布式集群中应用系统的一致性问题 高手 对于 Zookeeper 的理解…

并发编程笔记

1、前言 这篇笔记是我花的20多天跟着⿊⻢的并发编程学习做的笔记&#xff0c;地址是b站 ⿊⻢ 并发编程 &#xff0c;也是我第⼀次 学习并发 编程&#xff0c;所以如果有很多原理讲不清楚的&#xff0c;知识点不全的&#xff0c;也请多多包涵 中间多数图都是直接截⽼师的笔记…

基于Java SSM框架+Vue实现疫情期间医院门诊网站项目【项目源码+论文说明】

基于java的SSM框架Vue实现疫情期间医院门诊网站演示 摘要 21世纪的到来&#xff0c;国家的方方面面、各行各业都在努力与现代的先进技术接轨&#xff0c;智能科技时代崛起的优势&#xff0c;医院门诊管理系统当然也不能排除在外。疫情期间医院门诊管理系统是以实际运用为开发背…

【JVM系列】Class文件分析

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

终端安全管理软件是监控软件吗

有些人在后台问&#xff0c;终端安全管理软件是监控软件吗&#xff1f; 先回答&#xff0c;是监控软件。 因为它具有监控的功能&#xff0c;在很大程度上&#xff0c;是可以用来当做监控软件来用的。 终端安全管理软件是一种集中管理终端设备的软件工具&#xff0c;可以在企业…

猜数字赢金币

充值金币后开始游戏&#xff0c;猜中奖励10金币退出&#xff0c;不中扣除1金币继续。 (笔记模板由python脚本于2023年12月03日 21:52:23创建&#xff0c;本篇笔记适合熟悉程序函数式编程&#xff0c;熟练掌握基本数据类型的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网&…

linux常用命令-find命令与scp命令详解(超详细)

文章目录 前言一、find命令介绍1. find命令简介2. find命令的基本语法3. 常用的find命令选项和表达式 二、find命令示例用法1. 按照名称进行搜索2. 按照类型进行搜索3. 按照修改时间进行搜索4. 按照文件大小进行搜索5. 对搜索到的文件执行指定的命令6. 删除搜索到的文件 三、sc…

线程池怎么用?---实例讲解

线程池使用实例 先写一个配置类 /*** 线程池配置*/ Configuration public class ThreadPoolConfig {//定义线程前缀public static final String NAME_PRE"test";/*** ExecutorService 这个对象就是线程池&#xff0c;可以点进去他的源码看看* Bean&#xff0c;将ge…

2024年甘肃省职业院校技能大赛(中职教师组)网络安全竞赛样题卷③

2024年甘肃省职业院校技能大赛&#xff08;中职教师组&#xff09;网络安全竞赛样题卷③ 2024年甘肃省职业院校技能大赛&#xff08;中职教师组&#xff09;网络安全竞赛样题卷③A模块基础设施设置/安全加固&#xff08;200分&#xff09;A-1任务一 登录安全加固&#xff08;Wi…

400页Python学习PDF笔记,全面总结零基础入门看这一篇足够了

我们都知道Python入门比较简单&#xff0c;但仍有很多想要学习的新手依然卡在基础的安装阶段&#xff0c;尽管如此&#xff0c;网络上的大部分的教程却对这些基础内容都是一带而过&#xff0c;导致许多新手朋友对这些基础知识一知半解&#xff0c;往往一个小问题都需要在网上查…