二叉树与优先级队列

1.树

树是由n个数据构成的非线性结构,它是根朝上,叶朝下。

注意:树形结构之中,子树之间不能连接,不然就不构成树形结构

1.子树之间没有交集

2.除了根节点以外,每一个节点有且只有一个父亲节点

3.一个n个节点的树,有n-1条边

1.1树的一些概念

结点的度:一个结点含有子树的个数称为该结点的度; 如上图:A的度为6

树的度:一棵树中,所有结点度的最大值称为树的度; 如上图:树的度为6

叶子结点或终端结点:度为0的结点称为叶结点; 如上图:B、C、H、I...等节点为叶结点 双亲结点或父结点:若一个结点含有子结点,则这个结点称为其子结点的父结点; 如上图:A是B的父结点

孩子结点或子结点:一个结点含有的子树的根结点称为该结点的子结点; 如上图:B是A的孩子结点

根结点:一棵树中,没有双亲结点的结点;如上图:A 

结点的层次:从根开始定义起,根为第1层,根的子结点为第2层,以此类推

树的高度或深度:树中结点的最大层次; 如上图:树的高度为4 树的以下概念只需了解,

非终端结点或分支结点:度不为0的结点; 如上图:D、E、F、G...等节点为分支结点

兄弟结点:具有相同父结点的结点互称为兄弟结点; 如上图:B、C是兄弟结点

堂兄弟结点:双亲在同一层的结点互为堂兄弟;如上图:H、I互为兄弟结点

结点的祖先:从根到该结点所经分支上的所有结点;如上图:A是所有结点的祖先

子孙:以某结点为根的子树中任一结点都称为该结点的子孙。如上图:所有结点都是A的子孙

森林:由m(m>=0)棵互不相交的树组成的集合称为森林

2.二叉树

2.1概念

一棵二叉树的节点是有限集合

对于任意的二叉树,都是由下列情况组合而成

2.2两种特殊的二叉树

1.满二叉树:一棵二叉树树,每一层的节点数都到达了最大值,那么这就是满二叉树。也就是说如果一棵二叉树是k层,那么这棵树的节点树,且结点总数是2^{k}-1,则它就是满二叉树。

2.完全二叉树:完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的。对于深度为K的,有n 个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从0至n-1的结点一一对应时称之为完全二叉树。 要注意的是满二叉树是一种特殊的完全二叉树。

2.3二叉树的性质

1. 若规定根结点的层数为1,则一棵非空二叉树的第i层上最多有(i>0)个结点

2. 若规定只有根结点的二叉树的深度为1,则深度为K的二叉树的最大结点数是2^{k}-1(k>=0)

3. 对任何一棵二叉树, 如果其叶结点个数为 n0, 度为2的非叶结点个数为 n2,则有n0=n2+1

4. 具有n个结点的完全二叉树的深度k为\log_{2}n+1上取整

5. 对于具有n个结点的完全二叉树,如果按照从上至下从左至右的顺序对所有节点从0开始编号,对于序号为i 的结点有:

                若i>0,双亲序号:(i-1)/2;i=0,i为根结点编号,无双亲结点

              若2i+1<n  左孩子序号:2i+1,否则没有左孩子

              若2i+2<n  右孩子序号:2i+1,否则没有右孩子

2.4二叉树的存储

二叉树的存储结构分为:顺序存储和类似于链表的链式存储。

二叉树的链式存储是通过一个一个的节点引用起来的,常见的表示方式有二叉和三叉表示方式,具体如下

//孩子表示法
class Node {int val;  //用于储存数据Node left; //表示左孩子,通常为以左子树为根节点的二叉树Node right;  //表示右孩子,通常为右子树为根节点的二叉树
}
// 孩子双亲表示法
class Node {int val;        // 数据域Node left;      // 左孩子的引用,常常代表左孩子为根的整棵左子树Node right;     // 右孩子的引用,常常代表右孩子为根的整棵右子树Node parent;    // 当前节点的根节点
}

2.2二叉树的基本操作

存储方式是孩子表示方法

BinaryTree类

import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;public class BinaryTree {public static class TreeNode {public int val;public TreeNode left;//储存左子树public TreeNode rigth;//储存右子树public TreeNode(int val) {this.val = val;}@Overridepublic String toString() {return "TreeNode{" +"val=" + val +'}';}}//创建一个二叉树public TreeNode createbinarytree() {TreeNode A = new TreeNode(1);TreeNode B = new TreeNode(2);TreeNode C = new TreeNode(3);TreeNode D = new TreeNode(4);TreeNode E = new TreeNode(5);TreeNode F = new TreeNode(6);TreeNode G = new TreeNode(7);TreeNode H = new TreeNode(8);//连接数的结构A.left = B;A.rigth = C;B.left = D;B.rigth = E;C.left = F;C.rigth = G;E.rigth = H;return A;}//先实现三种遍历方法// 前序遍历public void preOrder(TreeNode root) {//NLR:前序遍历(Preorder Traversal 亦称先序遍历)——访问根结点--->根的左子树--->根的右子树。//递归的结束条件if (root == null) {return;}System.out.print(" " + root.val);preOrder(root.left);preOrder(root.rigth);//走到结尾这个循环结束}//不使用递归的的方法实现前序遍历public void preOrder1(TreeNode root){//借用栈来实现if(root==null){return ;}Stack<TreeNode> stack=new Stack<>();TreeNode cur=root;while(cur!=null||!stack.isEmpty()){while(cur!=null){stack.push(cur);System.out.print(cur.val+" ");cur=cur.left;}TreeNode top=stack.pop();cur=top.rigth;}}// 中序遍历public void inOrder(TreeNode root) {//LNR:中序遍历(Inorder Traversal)——根的左子树--->根节点--->根的右子树。if (root == null) {return;}inOrder(root.left);System.out.print(" " + root.val);inOrder(root.rigth);}//不使用递归的的方法实现中序遍历public void inOrder1(TreeNode root){//借用栈来实现iif(root==null){return ;}Stack<TreeNode> stack=new Stack<>();TreeNode cur=root;while(cur!=null||!stack.isEmpty()){while(cur!=null){stack.push(cur);cur=cur.left;}TreeNode top=stack.pop();System.out.print(top.val+" ");cur=top.rigth;}}// 后序遍历public void postOrder(TreeNode root) {//LRN:后序遍历(Postorder Traversal)——根的左子树--->根的右子树--->根节点。if (root == null) {return;}postOrder(root.left);postOrder(root.rigth);System.out.print(" " + root.val);}//使用不递归的方法使用后序遍历public void postOrder1(TreeNode root){//借用栈来实现if(root==null){return ;}Stack<TreeNode> stack=new Stack<>();TreeNode cur=root;TreeNode prve=null;while(cur!=null||!stack.isEmpty()){while(cur!=null){stack.push(cur);cur=cur.left;}TreeNode top=stack.peek();if(top==null||top.rigth==prve){System.out.println(top.val+" ");prve= stack.pop();}else{cur=top.rigth;}}}//获取数中节点个数public int nodesize;//第一种遍历式获取public void Nodesize1(TreeNode root) {//采用前序遍历if (root == null) {return;}//遇见节点将打印改成nodesize++nodesize++;Nodesize1(root.left);Nodesize1(root.rigth);}//第二种获取节点个数方法//左子树节点个数+右子树节点个数+根节点个数public int Nodesize2(TreeNode root) {if (root == null) {return 0;}return Nodesize2(root.left) + Nodesize2(root.rigth) + 1;}// 获取叶子节点的个数//依旧两种方法//第一遍种历二叉树public int getLeafNodeCount;public void getLeafNodeCount1(TreeNode root) {if (root == null) {return;}if (root.left == null && root.rigth == null) {getLeafNodeCount++;}getLeafNodeCount1(root.left);getLeafNodeCount1(root.rigth);}//第二种获取叶子节点个数//左子树叶子+右子树叶子节点个数public int getGetLeafNodeCount2(TreeNode root) {if (root == null) {return 0;}if (root.left == null && root.rigth == null) {return 1;}return getGetLeafNodeCount2(root.left) + getGetLeafNodeCount2(root.rigth);}// 获取第K层节点的个数public int getKLevelNodeCount(TreeNode root, int k) {//统计k层的节点个数,先找到第k-1层if (k == 1) {if (root == null) {return 0;} else {return 1;}}return getKLevelNodeCount(root.left, k - 1) + getKLevelNodeCount(root.rigth, k - 1);}// 获取二叉树的高度public int getHeight(TreeNode root) {//二叉树的高度等于左子树高度和右子树高度的最大值if(root==null) {return 0;}return getHeight(root.left)>getHeight(root.rigth)?getHeight(root.left)+1:getHeight(root.rigth)+1;}// 检测值为value的元素是否存在public TreeNode find(TreeNode root, int val){if(root.val==val){return root;}if(root.left!=null){TreeNode leftT=find(root.left,val);if(leftT!=null){return leftT;}}if(root.rigth!=null){TreeNode rigthT =find(root.rigth,val);if(rigthT!=null){return rigthT;}}return null;}//层序遍历public void levelOrder(TreeNode root){if(root==null){return;}//创建一个队列Queue<TreeNode> queue=new LinkedList<>();queue.offer(root);TreeNode cur=root;while(!queue.isEmpty()){//先将队列元素弹出cur=queue.poll();System.out.print(cur.val+" ");if(cur.left!=null){queue.offer(cur.left);}if(cur.rigth!=null){queue.offer(cur.rigth);}}System.out.println();}// 判断一棵树是不是完全二叉树public  boolean isCompleteTree(TreeNode root){//完全二叉树从左到右依次填满Queue<TreeNode> queue=new LinkedList<>();TreeNode cur=root;queue.offer(cur);while(queue.peek()!=null){cur=queue.poll();queue.offer(cur.left);queue.offer(cur.rigth);}while(!queue.isEmpty()){if(queue.poll()!=null){return false;}}return true;}public static void main(String[] args) {}
}

Test类

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;public class Test {public static void main(String[] args) {//调用创建二叉树BinaryTree binaryTree=new BinaryTree();//调用类中2的成员变量BinaryTree.TreeNode root=binaryTree.createbinarytree();//测试前序遍历打印binaryTree.preOrder(root);System.out.println();//  //测试前序遍历打印1binaryTree.preOrder1(root);System.out.println();System.out.println("==============================");System.out.println();//测试中序遍历binaryTree.inOrder(root);System.out.println();//测试中序遍历的非递归方法binaryTree.inOrder1(root);System.out.println("===============================");System.out.println();//测试后序遍历binaryTree.postOrder(root);System.out.println();//测试后续遍历的非递归方法binaryTree.postOrder1(root);System.out.println("=========================");System.out.println();//打印节点个数binaryTree.Nodesize1(root);System.out.println("二叉树结点个数:"+binaryTree.nodesize);//测试第二种打印节点个数方法System.out.println("二叉树结点个数:"+binaryTree.Nodesize2(root));//测试第一种叶子节点个数binaryTree.getLeafNodeCount1(root);System.out.println("二叉树叶子节点个数:"+binaryTree.getLeafNodeCount);//测试第二种叶子节点个数System.out.println("二叉树叶子节点个数:"+binaryTree.getGetLeafNodeCount2(root));//测试统计第k层的节点个数System.out.println("第1层的节点个数为"+binaryTree.getKLevelNodeCount(root, 1));System.out.println("第2层的节点个数为"+binaryTree.getKLevelNodeCount(root, 2));System.out.println("第3层的节点个数为"+binaryTree.getKLevelNodeCount(root, 3));System.out.println("第4层的节点个数为"+binaryTree.getKLevelNodeCount(root, 4));//测试计算二叉树的高度System.out.println("二叉树的高度为:"+binaryTree.getHeight(root));//测试二叉树的是否存在的元素List<List<Integer>> llist=new ArrayList<List<Integer>>();List<Integer> list1=new ArrayList<>();llist.add(list1);Queue<Integer> queue=new LinkedList<>();queue.offer(1);System.out.println(queue.poll());System.out.println("元素1存在节点"+binaryTree.find(root, 1)+"中");System.out.println("元素4存在节点"+binaryTree.find(root, 4)+"中");System.out.println("元素8存在节点"+binaryTree.find(root, 8)+"中");System.out.println("元素7存在节点"+binaryTree.find(root, 7)+"中");//测试二叉树的层序遍历binaryTree.levelOrder(root);//判断二叉树是否是完全二叉树System.out.println("判断这棵树是否是完全二叉树 "+binaryTree.isCompleteTree(root));}
}

3.优先队列(PriorityQueue)

3.1堆的性质

堆逻辑上是一颗完全二叉树,物理上是存储在数组中

总结:一颗完全二叉树以层序遍历方式放入数组中存储,这种方式的主要用法就是堆的表示。

  关于堆下标位置的计算

如果已知父亲(parent) 的下标,

则: 左孩子(left) 下标 = 2 * parent + 1;

       右孩子(right) 下标 = 2 * parent + 2;

已知孩子(不区分左右)(child)下标,

则:    双亲(parent) 下标 = (child - 1) / 2;

3.2堆的分类

大堆:根节点大于左右两个子节点的完全二叉树 (父亲节点大于其子节点),叫做大堆,或者大根堆,或者最大堆 。

小堆:根节点小于左右两个子节点的完全二叉树叫 小堆(父亲节点小于其子节点),或者小根堆,或者最小堆。

3.3堆的底层代码实现

创建小根堆

创建大根堆

向上调整

现在有一个堆,我们需要在堆的末尾插入数据,再对其进行调整,使其仍然保持堆的结构,这就是向上调整。

以大堆为例:

向下调整

堆的删除和添加

PriorityQueue类

import java.lang.reflect.Array;
import java.util.Arrays;public class PriorityQueue {public int[] elem;public int usedsize;public PriorityQueue() {this.elem=new int[10];}public void initelem(int [] array){for(int i=0;i<array.length;i++){this.elem[i]=array[i];usedsize++;}}public void elempeek(){for(int i=0;i<this.usedsize;i++){System.out.print(elem[i]+" ");}}//创建小根堆public void Smallrootpiles(){//小根堆的节点数要大于子树//第一步先确定有多少个树,利用最后一个节点来找到父亲节点for(int parent=(usedsize-1-1)/2;parent>=0;parent--){//也是一样采用向下调整的方法siftDown2(parent,usedsize);}}public void siftDown2(int parent,int usedsize){//parent:代表调整子树的起始位置//usedsize:判断子树是否还需要调整//1.根据父亲节点,找到左子树孩子节点int child=parent*2+1;//2.找到孩子之间的最小值while(child<usedsize){if(child+1<usedsize&&elem[child]>elem[child+1]){child++;}if(elem[child]<elem[parent]){int num=elem[parent];elem[parent]=elem[child];elem[child]=num;parent=child;child=child*2+1;}else{break;}}}//创建大根堆public void  createhead(){//大根堆的节点数要大于子树//第一步先确定有多少个树,利用最后一个节点来找到父亲节点for(int parent=(usedsize-1-1)/2;parent>=0;parent--){//采用向下调整siftDown1(parent,usedsize);}}//parent:代表调整子树的起始位置//usedsize:判断子树是否还需要调整public void siftDown1(int parent,int usedsize){//根据父亲节点找到左子树节点int child=parent*2+1;while(child<usedsize){if(child+1<usedsize&&elem[child]<elem[child+1]){child++;}if(elem[child]>elem[parent]){int num=elem[parent];elem[parent]=elem[child];elem[child]=num;
//                elem[child]=elem[child]^elem[parent];
//                elem[parent]=elem[child]^elem[parent];
//                elem[child]=elem[child]^elem[child];parent=child;child=child*2+1;}else{break;}}}//向堆中增加元素public void push(int val) {//先进行判满处理if (isFull()) {//进行扩容elem = Arrays.copyOf(elem, elem.length * 2);}elem[usedsize] = val;usedsize++;siftUp(usedsize - 1);}//向上调整public void siftUp(int child) {//孩子节点找到父亲节点int parent=(child-1)/2;//向上调整while(parent>=0){if(elem[child]>elem[parent]){int num=elem[parent];elem[parent]=elem[child];elem[child]=num;child=parent;parent=(parent-1)/2;}else{break;}}}public boolean isFull(){if(usedsize==this.elem.length){return true;}return false;}//删除堆的元素public int poll(){if(isEmpty()){return -1;}int val=elem[0];//交换0位置和最后一个节点位置elem[0]=elem[usedsize-1];elem[usedsize-1]=val;//对0节点位置进行向下调整siftDown1(0,usedsize-1);usedsize--;return val;}//判段是否为空public boolean isEmpty(){if (usedsize==0){return true;}return false;}//对节点进行排从小到大排序(再节点本身上排序)public void headsort(){//先对数据进行建大堆this.createhead();int end=usedsize-1;while(end>0){int num=elem[0];elem[0]=elem[end];elem[end]=num;siftDown1(0,end);end--;}}public static void main(String[] args) {}
}

Test类

public class Test {public static void main(String[] args) {//对队进行初始化PriorityQueue priorityQueue=new PriorityQueue();int[] array={ 27,15,19,18,28,34,65,49,25,37 };priorityQueue.initelem(array);//测试建立小根堆priorityQueue.Smallrootpiles();priorityQueue.elempeek();System.out.println();//测试大根堆的实现priorityQueue.createhead();priorityQueue.elempeek();//测试插入一个元素priorityQueue.push(80);System.out.println();priorityQueue.elempeek();//测试删除一个元素priorityQueue.poll();System.out.println();priorityQueue.elempeek();System.out.println();//测试堆排序priorityQueue.headsort();priorityQueue.elempeek();//}
}

3.4堆的问题

3.4.1topk问题

给你6个数据,求前3个最大数据。这时候我们用堆怎么做的?

解题思路:

1、如果求前K个最大的元素,要建一个小根堆。

2、如果求前K个最小的元素,要建一个大根堆。

3、第K大的元素。建一个小堆,堆顶元素就是第K大的元素。

4、第K小的元素。建一个大堆,堆顶元素就是第K大的元素。

3.4.2数组的排序

再者说如果要对一个数组进行从小到大排序,要借助大根堆还是小根堆呢?

---->大根堆

3.5PriorityQueue

使用注意:

1. 使用时必须导入PriorityQueue所在的包,即:

import java.util.PriorityQueue; 

2. PriorityQueue中放置的元素必须要能够比较大小,不能插入无法比较大小的对象,否则会抛出 ClassCastException异常

3. 不能插入null对象,否则会抛出NullPointerException

4. 没有容量限制,可以插入任意多个元素,其内部可以自动扩容

5. 插入和删除元素的时间复杂度为

6. PriorityQueue底层使用了堆数据结构

7. PriorityQueue默认情况下是小堆---即每次获取到的元素都是最小的元素

1.优先级队列的构造

static void TestPriorityQueue(){// 1.创建一个空的优先级队列,底层默认容量是11PriorityQueue<Integer> q1 = new PriorityQueue<>();// 2.创建一个空的优先级队列,底层的容量为initialCapacityPriorityQueue<Integer> q2 = new PriorityQueue<>(100);ArrayList<Integer> list = new ArrayList<>();list.add(4);list.add(3);list.add(2);list.add(1);// 用ArrayList对象来构造一个优先级队列的对象// q3中已经包含了三个元素PriorityQueue<Integer> q3 = new PriorityQueue<>(list);System.out.println(q3.size());System.out.println(q3.peek());}//注意:默认情况下,PriorityQueue队列是小堆,如果需要大堆需要用户提供比较器// 用户自己定义的比较器:直接实现Comparator接口,然后重写该接口中的compare方法即可
class IntCmp implements Comparator<Integer>{@Overridepublic int compare(Integer o1, Integer o2) {return o2-o1;}}public class TestPriorityQueue {public static void main(String[] args) {PriorityQueue<Integer> p = new PriorityQueue<>(new IntCmp());p.offer(4);p.offer(3);p.offer(2);p.offer(1);p.offer(5)

自定义排序规则

1.该改变升序降序

2.根据HashMap的value值对HashMap的键值对排序

方法摘要

 System.out.println(p.peek());}}static void TestPriorityQueue2(){int[] arr = {4,1,9,2,8,0,7,3,6,5};// 一般在创建优先级队列对象时,如果知道元素个数,建议就直接将底层容量给好// 否则在插入时需要不多的扩容// 扩容机制:开辟更大的空间,拷贝元素,这样效率会比较低PriorityQueue<Integer> q = new PriorityQueue<>(arr.length);for (int e: arr) {q.offer(e);}System.out.println(q.size());   // 打印优先级队列中有效元素个数System.out.println(q.peek());   // 获取优先级最高的元素// 从优先级队列中删除两个元素之和,再次获取优先级最高的元素q.poll();q.poll();System.out.println(q.size());   // 打印优先级队列中有效元素个数System.out.println(q.peek());   // 获取优先级最高的元素q.offer(0);System.out.println(q.peek());   // 获取优先级最高的元素// 将优先级队列中的有效元素删除掉,检测其是否为空q.clear();if(q.isEmpty()){System.out.println("优先级队列已经为空!!!")}else{System.out.println("优先级队列不为空");}}

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

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

相关文章

如何进行室内VR全景拍摄?

如何进行室内VR全景拍摄&#xff1f; 室内VR全景拍摄作为先进的视觉技术&#xff0c;能够为用户提供沉浸式的空间体验。本文介绍如何进行室内VR全景拍摄&#xff0c;并阐述众趣科技在这一领域的技术支持和服务优势。 室内VR全景拍摄基础 1. 室内VR全景拍摄概述 室内VR全景拍…

如何通过代理 IP 实现异地直播推流

在直播行业日益火爆的今天&#xff0c;许多主播希望突破地域限制&#xff0c;实现异地直播推流&#xff0c;以获得更广泛的观众群体和更好的直播效果。代理 IP 作为一种有效的网络工具&#xff0c;能够帮助主播轻松达成这一目标。本文将详细介绍如何通过代理 IP 实现异地直播推…

随机变量数字特征

主要介绍一维随机变量期望和方差、二维随机变量期望和方差、以及协方差相关公式&#xff0c;及推导。 一维随机变量 以一个抛硬币的场景作为例子&#xff0c;如下&#xff1a; 抛掷两枚均匀硬币&#xff0c;如果两枚都是正面向上&#xff0c;则赢得2元&#xff0c;否则就输掉…

上传图片后,如何调用API进行商品搜索?

以下是一个完整的示例&#xff0c;展示如何在上传图片后调用淘宝按图搜索商品&#xff08;拍立淘&#xff09;API进行商品搜索&#xff1a; 1. 准备工作 注册账号并获取API密钥&#xff1a;在淘宝开放平台注册账号&#xff0c;创建应用&#xff0c;获取app_key和app_secret。 …

Android 数据持久化之 Room 数据库存储

一、简介 Room 是 Google 推出的 Android 持久层框架,建立在 SQLite 之上,提供了一个抽象层,简化了数据库操作。它通过注解和编译时检查来确保数据操作的正确性。 Room 主要由以下三个组件组成: Entity(实体):定义封装实际数据的实体类,每个实体类对应数据库中的一个…

react中的用法——setDisabled dva dispatch effects

setDisabled 在react中&#xff0c;setDisabled通常是指通过状态管理来控制某个组件&#xff08;如按钮、输入框等&#xff09;的禁用状态。虽然react本身没有内置的setDisabled方法&#xff0c;但你可以使用useState钩子来实现类似的功能。以下是一个简单的示例&#xff0c;展…

html css js网页制作成品——HTML+CSS珠海网页设计网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…

C语言复习笔记--自定义类型

今天我们来复习一下自定义类型.自定义类型大概分为结构体,枚举,联合体,数组这几种.数组在之前就介绍过.今天我们来看下其他三种. 结构体 首先来看结构体. 结构体类型的声明 之前在操作符的地方简单认识过结构体.下面我们回顾一下. 结构体回顾 结构是⼀些值的集合&#xff0c;这…

python jupyter notebook

什么是Jupyter Notebook Jupyter Notebook是一个开源的Web应用程序&#xff0c;允许用户创建和共享包含实时代码、方程、可视化和解释性文本的文档。它最初由IPython团队开发&#xff0c;现在已经成为一个独立的项目&#xff0c;并广泛用于数据清理和转换、数值模拟、统计建模…

Linux——https基础理论

1. 初步认识https协议 • 属于应用层 • 相较于http协议&#xff0c;https在应用层多了一层加密层&#xff0c;为了保证数据安全 • 简单理解&#xff1a;https就是对http的加密和解密 2. 中间人攻击 • 数据在传输过程中&#xff0c;遭第三方篡改。 3. 加密方式 • 对称加密&a…

在 C++ 中对类型进行排序

0.前言 在 C 中&#xff0c;我编写了一个 tuple-like 模板&#xff0c;这个模板能容纳任意多且可重复的类型&#xff1a; template<typename... Ts> struct TypeList {};// usage: using List1 TypeList<int, double, char, double>; using List2 TypeList<…

Unity-Socket通信实例详解

今天我们来讲解socket通信。 首先我们需要知道什么是socket通信&#xff1a; Socket本质上就是一个个进程之间网络通信的基础&#xff0c;每一个Socket由IP端口组成&#xff0c;熟悉计网的同学应该知道IP主要是应用于IP协议而端口主要应用于TCP协议&#xff0c;这也证明了Sock…

使用Go语言对接全球股票数据源API实践指南

使用Go语言对接全球股票数据API实践指南 概述 本文介绍如何通过Go语言对接支持多国股票数据的API服务。我们将基于提供的API文档&#xff0c;实现包括市场行情、K线数据、实时推送等核心功能的对接。 一、准备工作 1. 获取API Key 联系服务提供商获取访问密钥&#xff08;替…

LeetCode 热题 100 17. 电话号码的字母组合

LeetCode 热题 100 | 17. 电话号码的字母组合 大家好&#xff0c;今天我们来解决一道经典的算法题——电话号码的字母组合。这道题在 LeetCode 上被标记为中等难度&#xff0c;要求给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。下面我将详细讲解解…

OpenCV计算机视觉实战(3)——计算机图像处理基础

OpenCV计算机视觉实战&#xff08;3&#xff09;——计算机图像处理基础 0. 前言1. 像素和图像表示1.1 像素 2. 色彩空间2.1 原色2.2 色彩空间2.3 像素和色彩空间 3. 文件类型3.1 图像文件类型3.2 视频文件3.3 图像与视频 4. 计算机图像编程简史5. OpenCV 概述小结系列链接 0. …

Vite 的工作流程

Vite 的工作流程基于其创新的 “预构建 按需加载” 机制&#xff0c;通过利用现代浏览器对原生 ES 模块的支持&#xff0c;显著提升了开发效率和构建速度。以下是其核心工作流程的详细分析&#xff1a; 一、开发环境工作流程 1. 启动开发服务器 冷启动&#xff1a;通过 npm …

线性DP(动态规划)

线性DP的概念&#xff08;视频&#xff09; 学习线性DP之前&#xff0c;请确保已经对递推有所了解。 一、概念 1、动态规划 不要去看网上的各种概念&#xff0c;什么无后效性&#xff0c;什么空间换时间&#xff0c;会越看越晕。从做题的角度去理解就好了&#xff0c;动态规划…

MySQL中sql_mode的设置

■ 57版本原来配置 show variables like %sql_mode%; STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION ■ 修改配置文件 注释掉sql_mode&#xff0c;并重启&#xff0c;查看57版本的默认设置 ONL…

MCAL学习(1)——AutoSAR

1.了解AutoSAR及一些概念 AutoSAR是Automotive Open System Architecture ,汽车开放系统架构。 针对汽车ECU的软件开发架构。已经是汽车电子软件开发的标准。 OS服务&#xff1a;Freertos 整车厂&#xff08;OEM&#xff09;主要负责应用层算法 一级供应商&#xff1a;生产制…

Vue报错:Cannot read properties of null (reading ‘xxx‘)

一、报错问题 Cannot read properties of null (reading style)at patchStyle (runtime-dom.esm-bundler.js:104:22)二、错误排查 这类报错一般是在已经开发好后&#xff0c;后面测试时突然发现的&#xff0c;所以不好排查错误原因。 三、可能原因及解决方案 v-if 导致 在 …