【数据结构】 排序算法

  • 一、排序
    • 1.1 排序是什么?
    • 1.2 排序的应用
    • 1.3 常见排序算法
  • 二、常见排序算法的实现
    • 2.1 插入排序
      • 2.1.1 直接插入排序
      • 2.1.2 希尔排序
    • 2.2 选择排序
      • 2.2.1 直接选择排序
        • 2.2.1.1 方法1
        • 2.2.1.1 方法2
      • 2.2.2 堆排序(数组形式)
    • 2.3 交换排序
      • 2.3.1 冒泡排序
      • 2.3.2 快速排序
        • 2.3.2.1 Hoare版 快速排序
        • 2.3.2.2 挖坑法 快速排序
      • 2.3.3 快排的优化
      • 2.3.4 快速排序非递归
    • 2.4 归并排序
  • 三、各排序算法的复杂度及稳定性
  • 四、 其他排序
    • 4.1 计数排序
    • 4.2 基数排序
    • 4.3 桶排序

一、排序

1.1 排序是什么?

在这里插入图片描述

1.2 排序的应用

在这里插入图片描述

1.3 常见排序算法

在这里插入图片描述

二、常见排序算法的实现

十大经典排序算法 动画演示

2.1 插入排序

2.1.1 直接插入排序

(1)图解

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(2)直接插入排序 解题思路
在这里插入图片描述

(3)Java 代码实现

public class Sort {/*** 直接插入排序* 时间复杂度: 最坏情况 O(N^2)  最好情况O(N) -- 数据有序的情况下* 直接插入排序使用场景: 给定的数据 趋于有序时,可以使用直接插入排序。* 稳定性: 稳定* @param array*/public static void insertSort(int[] array){for (int i = 1; i < array.length; i++) {//从第2个元素开始排序int tmp = array[i];int j = i-1;for (; j >= 0 ; j--) {if(array[j] > tmp){array[j+1] = array[j];}else{//array[j+1] = tmp;break;}}//j=-1,把tmp的值再放回来array[j+1] = tmp;}}
}

测试类:

import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Random;public class Test {//测试 直接排序法的时间效率//构造 有序数组public static void order(int[] array) {for (int i = 0; i < array.length; i++) {array[i] = i;}}//构造 逆序数组public static void  reverseOrder(int[] array){for (int i = 0; i < array.length; i++) {array[i] = array.length -i;}}//构造 随机数组public static void randomOrder(int[] array){Random random = new Random();for (int i = 0; i < array.length; i++) {array[i] = random.nextInt(array.length);}}public static void testInsertSort(int[] array){array = Arrays.copyOf(array,array.length);long startTime = System.currentTimeMillis();Sort.insertSort(array);long endTime = System.currentTimeMillis();System.out.println("直接插入排序耗时:"+(endTime-startTime));}public static void testShellSort(int[] array){array = Arrays.copyOf(array,array.length);long startTime = System.currentTimeMillis();Sort.insertSort(array);long endTime = System.currentTimeMillis();System.out.println("假设 希尔排序耗时:"+(endTime-startTime));}public static void main(String[] args) {int[] array = new int[1_0000];reverseOrder(array);testInsertSort(array);testShellSort(array);}public static void main1(String[] args) {int[] array = {81,12,31,4,15,6};Sort.insertSort(array);System.out.println(Arrays.toString(array));//[4, 6, 12, 15, 31, 81]}
}

2.1.2 希尔排序

(1)希尔排序法的基本思想:

先选定⼀个整数,把待排序⽂件中所有记录分成多个组,所有距离为的记录分在同⼀组内,并对每⼀组内的记录进⾏排序。然后,取,重复上述分组和排序的⼯作。当到达=1时,所有记录在统⼀组内排好序。

(2)图解
在这里插入图片描述
在这里插入图片描述
(3)Java 代码实现

/*** 希尔排序* 时间复杂度:O(n^1.3)* 空间复杂度:O(1)* 稳定性:不稳定* @param array*/public static void shellSort(int[] array){int gap = array.length / 2;while(gap > 0){shell(array,gap);gap /= 2;}shell(array,1);}public static void shell(int[] array,int gap){for (int i = gap; i < array.length; i++) {//从第2个元素开始排序int tmp = array[i];int j = i-gap;for (; j >= 0 ; j -= gap) {if(array[j] > tmp){array[j+gap] = array[j];}else{break;}}array[j+gap] = tmp;}}

2.2 选择排序

2.2.1 直接选择排序

2.2.1.1 方法1

(1)图解

在这里插入图片描述

在这里插入图片描述
(2)直接排序解题思路

在这里插入图片描述
(3)Java 代码实现

/*** 直接选择排序* 时间复杂度:O(N^2)* 空间复杂度:O(1)* 稳定性:不稳定*/public static void selectSort(int[] array){for (int i = 0; i < array.length; i++) {int minIndex = i;for (int j = i+1; j < array.length; j++) {if(array[minIndex] > array[j]){minIndex = j;}}swap(array,minIndex,i);}}private static void swap(int[] array,int i,int j){int tmp = array[i];array[i] = array[j];array[j] = tmp;}

测试类:

 public static void main(String[] args) {int[] array = {81,12,31,4,15,6};Sort.selectSort(array);System.out.println(Arrays.toString(array));//[4, 6, 12, 15, 31, 81]}
2.2.1.1 方法2

(1)图解
在这里插入图片描述

在这里插入图片描述
(2)Java 代码

 //选择排序 方法2/*** 每次找到2个数据 一个最大 一个最小*/public static void selectSort2(int[] array){int left = 0;int right = array.length-1;while(left < right){int minIndex = left;int maxIndex = left;for (int i = left+1; i <= right ; i++) {if(array[i] < array[minIndex]){minIndex = i;}if(array[i] > array[maxIndex]){maxIndex = i;}}swap(array,minIndex,left);//假设第一个值 是最大值 81 3 6 2 4if(left == maxIndex){maxIndex = minIndex;}swap(array,maxIndex,right);left++;right--;}}
}

2.2.2 堆排序(数组形式)

(1)图解
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
(2)Java 代码

//堆排序/*** 时间复杂度:O(n*log2n)* 空间复杂度:O(1)* 稳定性:不稳定*/public static void heapSort(int[] array){createHeap(array);int end = array.length -1;while(end > 0){swap(array,0,end);siftDown(array,0,end);end--;}}public static void createHeap(int[] array){for (int parent = (array.length-1-1)/2; parent >= 0 ; parent--) {siftDown(array,parent,array.length);}}public static void siftDown(int[] array,int parent,int length){int child = 2 * parent + 1;while(child < length){if(child+1 < length && array[child] < array[child+1]){//存在右孩子 并且 左孩子比右孩子小child++;}if(array[child] > array[parent]){swap(array,child,parent);parent = child;child = 2 * parent + 1;}else{break;}}}

2.3 交换排序

2.3.1 冒泡排序

    //冒泡排序/**当前代码是优化过的版本,分析时间复杂度的时候,不考虑优化情况* 时间复杂度:O(n^2);  如果考虑优化,最好情况下时间复杂度为O(n)* 空间复杂度:O(1)* 稳定性:稳定*/public static void bubbleSort(int[] array){//趟数:10个数据 比较9趟for (int i = 0; i < array.length-1; i++) {boolean flg = false;//未优化的版本:没有flg//每一趟的比较次数for (int j = 0; j < array.length-1-i; j++) {//未优化的版本:j < array.length-1if(array[j] > array[j+1]){swap(array,j,j+1);flg = true;}}if(!flg){break;}}}

2.3.2 快速排序

2.3.2.1 Hoare版 快速排序

(1)图解

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
(2)Java 代码实现

//Hoare版 快速排序/**时间复杂度:O((n^log2n)*                当前代码的最坏情况下:O(N^2) 有序 或 逆序*空间复杂度: O(log2n) 最好*           O(N) 最坏* 稳定性:不稳定*/public static void quickSort(int[] array){quick(array,0,array.length-1);}public static void quick(int[] array,int start,int end){if(start >= end){return;}int par = partition(array,start,end);quick(array,start,par-1);quick(array,par+1,end);}private static int partitionHoare(int[] array,int left,int right){int i = left;int tmp = array[left];while(left < right){while(left < right && array[right] >= tmp){right--;}while(left < right && array[left] <= tmp){left++;}swap(array,left,right);}swap(array,left,i);return left;}
2.3.2.2 挖坑法 快速排序
private static int partition(int[] array,int left,int right){int tmp = array[left];while(left < right){while(left < right && array[right] >= tmp){right--;}array[left] = array[right];while(left < right && array[left] <= tmp){left++;}array[right] = array[left];}array[left] = tmp;return left;}

2.3.3 快排的优化

  1. 三数取中

三数取中优化:

 //三数取中int index = midSum(array,start,end);swap(array,start,index);int par = partition2(array,start,end);quick(array,start,par-1);quick(array,par+1,end);}public static int midSum(int[] array,int left,int right){int mid = (left+right)/2;if(array[left] < array[right]){if(array[mid] < array[left]){return left;}else if(array[mid] > array[right]){return right;}else{return mid;}}else{if(array[mid] > array[left]){return left;}else if(array[mid] < array[right]){return right;}else{return mid;}}}

快速排序:

 //Hoare版 快速排序/**时间复杂度:O((n^log2n)*                当前代码的最坏情况下:O(N^2) 有序 或 逆序*空间复杂度: O(log2n) 最好*           O(N) 最坏* 稳定性:不稳定*/public static void quickSort(int[] array){quick(array,0,array.length-1);}public static void quick(int[] array,int start,int end){if(start >= end){return;}//三数取中int index = midSum(array,start,end);swap(array,start,index);int par = partition2(array,start,end);quick(array,start,par-1);quick(array,par+1,end);}public static int midSum(int[] array,int left,int right){int mid = (left+right)/2;if(array[left] < array[right]){if(array[mid] < array[left]){return left;}else if(array[mid] > array[right]){return right;}else{return mid;}}else{if(array[mid] > array[left]){return left;}else if(array[mid] < array[right]){return right;}else{return mid;}}}private static int partitionHoare(int[] array,int left,int right){int i = left;int tmp = array[left];while(left < right){while(left < right && array[right] >= tmp){right--;}while(left < right && array[left] <= tmp){left++;}swap(array,left,right);}swap(array,left,i);return left;}//挖坑法 快速排序private static int partition2(int[] array,int left,int right){int tmp = array[left];while(left < right){while(left < right && array[right] >= tmp){right--;}array[left] = array[right];while(left < right && array[left] <= tmp){left++;}array[right] = array[left];}array[left] = tmp;return left;}
  1. 递归到小的子区间时,可以考虑使用插入排序

直接插入排序:

 public static void quick(int[] array,int start,int end){if(start >= end){return;}if(end-start+1 <= 10){//采用直接插入排序,把当前区间排序insertSortRange(array,start,end);return;}//三数取中int index = midSum(array,start,end);swap(array,start,index);int par = partition2(array,start,end);quick(array,start,par-1);quick(array,par+1,end);}public static void insertSortRange(int[] array,int left,int right){for (int i = left+1; i <= right; i++) {int tmp = array[i];int j = i-1;for (; j >= left ; j--) {if(array[j] > tmp){array[j+1] = array[j];}else{break;}}array[j+1] = tmp;}}

快速排序:

    //Hoare版 快速排序/**时间复杂度:O((n^log2n)*                当前代码的最坏情况下:O(N^2) 有序 或 逆序*空间复杂度: O(log2n) 最好*           O(N) 最坏* 稳定性:不稳定*/public static void quickSort(int[] array){quick(array,0,array.length-1);}public static void quick(int[] array,int start,int end){if(start >= end){return;}if(end-start+1 <= 10){//采用直接插入排序,把当前区间排序insertSortRange(array,start,end);return;}//三数取中int index = midSum(array,start,end);swap(array,start,index);int par = partition2(array,start,end);quick(array,start,par-1);quick(array,par+1,end);}public static void insertSortRange(int[] array,int left,int right){for (int i = left+1; i <= right; i++) {int tmp = array[i];int j = i-1;for (; j >= left ; j--) {if(array[j] > tmp){array[j+1] = array[j];}else{break;}}array[j+1] = tmp;}}public static int midSum(int[] array,int left,int right){int mid = (left+right)/2;if(array[left] < array[right]){if(array[mid] < array[left]){return left;}else if(array[mid] > array[right]){return right;}else{return mid;}}else{if(array[mid] > array[left]){return left;}else if(array[mid] < array[right]){return right;}else{return mid;}}}private static int partitionHoare(int[] array,int left,int right){int i = left;int tmp = array[left];while(left < right){while(left < right && array[right] >= tmp){right--;}while(left < right && array[left] <= tmp){left++;}swap(array,left,right);}swap(array,left,i);return left;}//挖坑法 快速排序private static int partition2(int[] array,int left,int right){int tmp = array[left];while(left < right){while(left < right && array[right] >= tmp){right--;}array[left] = array[right];while(left < right && array[left] <= tmp){left++;}array[right] = array[left];}array[left] = tmp;return left;}
  1. 前后指针法 快速排序
//前后指针法 快速排序public static int partition(int[] array,int left,int right){int prev = left;int cur = left+1;while(cur <= right){if(array[cur] <= array[right] && array[++prev] != array[cur]){swap(array,cur,prev);}cur++;}swap(array,prev,left);return prev;

2.3.4 快速排序非递归

(1)图解
在这里插入图片描述
在这里插入图片描述
(2)Java 代码实现

 //非递归的快速排序/** 时间复杂度:O(N*logN)* 空间复杂度:O(logN)* 不稳定*/public static void quickSortNor(int[] array){int left = 0;int right = array.length -1;int par = partition2(array,left,right);Stack<Integer> stack = new Stack<>();//左边有2个元素及以上if(par > left+1){stack.push(left);stack.push(par-1);}//右边有2个元素及以上if(par < right-1){stack.push(par+1);stack.push(right);}//相当于把0 4 6 9扔进里面了while(!stack.isEmpty()){right = stack.pop();left = stack.pop();par = partition2(array,left,right);if(par > left+1){stack.push(left);stack.push(par-1);}//右边有2个元素及以上if(par < right-1){stack.push(par+1);stack.push(right);}}}

2.4 归并排序

(1)图解
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
(2)Java 代码实现

//归并排序/** 时间复杂度:O(N*log2N)*  空间复杂度:O(N)*  稳定*/public static void mergeSort(int[] array){mergeSortChild(array,0,array.length-1);}private static void mergeSortChild(int[] array,int left,int right){if( left>= right){return;}int mid = (left+right) / 2;mergeSortChild(array, left, mid);mergeSortChild(array, mid + 1, right);//开始合并merge(array, left, mid, right);}private static void merge(int[] array, int left, int mid, int right) {//临时数组int[] tmpArr = new int[right-left+1];int k = 0;//tmpArr数组下标int s1 = left;int e1 = mid;int s2 = mid+1;int e2 = right;//当2个段 都有数据的时候while(s1 <= e1 && s2 <= e2){if(array[s1] < array[s2]){tmpArr[k++] = array[s1++];}else{tmpArr[k++] = array[s2++];}}//一个段走完了 把另一个段的数据 拷贝到临时数组while(s1 <= e1){tmpArr[k++] = array[s1++];}while(s2 <= e2){tmpArr[k++] = array[s2++];}//临时数组当中存储的是有序的数组 --> 拷贝数据到原始数组当中for (int i = 0; i < k; i++) {array[i+left] = tmpArr[i];}}

(3)非递归 归并排序

//非递归 归并排序
public static void mergeSortNor(int[] array) {if (array == null || array.length <= 1) {return;}int gap = 1; // 初始子数组长度while (gap < array.length) {// 遍历整个数组,每次合并两个相邻的子数组for (int i = 0; i < array.length; i += 2 * gap) {int left = i;int mid = Math.min(i + gap - 1, array.length - 1); // 防止越界int right = Math.min(i + 2 * gap - 1, array.length - 1); // 防止越界// 合并 [left, mid] 和 [mid+1, right]merge(array, left, mid, right);}gap *= 2; // 子数组长度翻倍}}

三、各排序算法的复杂度及稳定性

在这里插入图片描述

四、 其他排序

4.1 计数排序

(1)图解
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
(2)java 代码实现

//计数排序/** 使用场景:数组集中在某个范围内*   时间复杂度:O(MAX(N,范围))*   空间复杂度:O(范围)*   稳定*/public static void countSort(int[] array){//1.求最大值 和 最小值int max = array[0];int min = array[0];for (int i = 1; i < array.length; i++) {if(array[i] < min){min = array[i];}if(array[i] > max){max = array[i];}}//2.定义计数数组,并求数组长度int len = max - min + 1;int[] countArray = new int[len];//3.遍历原始数组,计数数组开始计数for (int i = 0; i < array.length; i++) {int index = array[i] - min;countArray[index]++;}//4.遍历计数数组int k = 0;//array数组的新下标for (int i = 0; i < countArray.length; i++) {while(countArray[i] != 0){array[k] = i+min;k++;countArray[i]--;}}//执行到这里 array数组全部都有序了}

4.2 基数排序

4.3 桶排序

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

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

相关文章

NumPy-核心函数np.matmul()深入解析

NumPy-核心函数np.matmul深入解析 一、矩阵乘法的本质与np.matmul()的设计目标1. 数学定义&#xff1a;从二维到多维的扩展2. 设计目标 二、np.matmul()核心语法与参数解析函数签名核心特性 三、多维场景下的核心运算逻辑1. 二维矩阵乘法&#xff1a;基础用法2. 一维向量与二维…

突破政务文档理解瓶颈:基于多模态大模型的智能解析系统详解

重磅推荐专栏&#xff1a; 《大模型AIGC》 《课程大纲》 《知识星球》 本专栏致力于探索和讨论当今最前沿的技术趋势和应用领域&#xff0c;包括但不限于ChatGPT、DeepSeek、Stable Diffusion等。我们将深入研究大型模型的开发和应用&#xff0c;以及与之相关的人工智能生成内容…

深入探讨支持向量机(SVM)在乳腺癌X光片分类中的应用及实现

🧑 博主简介:CSDN博客专家、CSDN平台优质创作者,高级开发工程师,数学专业,10年以上C/C++, C#, Java等多种编程语言开发经验,拥有高级工程师证书;擅长C/C++、C#等开发语言,熟悉Java常用开发技术,能熟练应用常用数据库SQL server,Oracle,mysql,postgresql等进行开发应用…

九、K8s污点和容忍

九、K8s污点和容忍 文章目录九、K8s污点和容忍1、污点&#xff08;Taint&#xff09;和容忍&#xff08;Toleration&#xff09;1.1 什么是污点&#xff08;Taint&#xff09;&#xff1f;1.2 什么是容忍&#xff08;Toleration&#xff09;&#xff1f;1.3 污点的影响效果&…

基于开源AI智能名片链动2+1模式S2B2C商城小程序的超级文化符号构建路径研究

摘要&#xff1a;在数字技术重构文化传播生态的背景下&#xff0c;超级文化符号的塑造已突破传统IP运营框架。本文以开源AI智能名片链动21模式与S2B2C商城小程序的融合创新为切入点&#xff0c;结合"屿光生活"体验馆、快手烧烤摊主等典型案例&#xff0c;提出"技…

QT 日志 - qInstallMessageHandler将qDebug()打印内容输出到文件

在编程开发中&#xff0c;日志功能至关重要&#xff0c;对于在开发期间或者是程序上线后&#xff0c;都有助于排查问题&#xff1b; 对于C/C和QT方向&#xff0c;日志库有log4cpp、plog、log4qt等&#xff0c;本篇文章将使用qt自带的日志方式去实现。 定义日志函数&#xff1a…

记录一下seata启动403问题

1.现象&#xff1a;启动报错可能是403&#xff0c;或是是密码错误一般是nacos加了认证&#xff0c;seata配置nacos账号密码的时候就启动不了。可能是密码错误&#xff0c;最有可能是seata版本太低导致的。1.4.2以及一下的版本应该都有这个问题2.问题密码不能有特殊符号如&#…

【STM32实践篇】:GPIO 详解

文章目录GPIO 基本结构GPIO 工作模式GPIO 基本结构 右边的红框是I/O引脚&#xff0c;这个I/O引脚就是我们可以看到的芯片实物的引脚&#xff0c;其他部分都是GPIO的内部结构。 保护二极管 上方二极管用于防过压保护&#xff0c;当I/O引脚电压高于 V_DD 二极管导通压降​时&…

#include

关于 C 中的 include <>和 include “” 这两种形式&#xff0c;区别其实是关于“搜索路径”和“优先级”的。让我详细为你讲解。 1. 简单区别总结 #include <header>&#xff1a;告诉编译器去“系统标准目录”或“预定义的标准路径”中查找头文件&#xff08;比如…

永磁同步电机参数辨识算法--带遗忘因子的递推最小二乘法辨识

一、原理介绍之前已经介绍了递推最小二乘法进行电气参数辨识&#xff0c;在实时参数辨识中&#xff0c;协方差矩阵P和增益矩阵K是用于更新参数估计的重要工具&#xff0c;而系统参数变化时&#xff0c;P、K矩阵会逐渐减小&#xff0c;导致数据饱和。数据饱和与参数迟滞是实时参…

JVM 知识点

一、JVM 概述JVM&#xff08;Java Virtual Machine&#xff09;即 Java 虚拟机&#xff0c;它是 Java 编程语言的核心组件之一&#xff0c;负责执行 Java 程序。JVM 使得 Java 程序可以实现“一次编写&#xff0c;到处运行”的特性&#xff0c;因为它提供了一个抽象的运行环境&…

windows装机

1、制作启动盘 2、制作启动盘 启动盘中含有WinPE系统和ISO 3、从U盘启动&#xff0c;加载ISO 4、执行ISO中的setup安装win10 5、之后从C盘启动进入win10系统 6、安装“华为电脑管家”,安装驱动 华为电脑管家官方下载-笔记本驱动更新 | 华为官网 7、下载安装必要软件 https://…

提示技术系列(13)——ReAct

什么是提示技术&#xff1f; 提示技术是实现提示工程目标的具体技术手段&#xff0c;是提示工程中的“工具库”。 什么又是提示工程&#xff1f; 提示工程是指通过设计、优化和迭代输入到大语言模型&#xff08;LLM&#xff09;的提示&#xff08;Prompt&#xff09;&#xff…

【SVO】klt与极限搜索块匹配findEpipolarMatchDirect

Matcher::findEpipolarMatchDirect 函数逻辑与原理分析 核心目标&#xff1a; 在极线上搜索参考帧特征点 ref_ftr 在当前帧 cur_frame 中的最佳匹配点&#xff0c;并通过三角化计算深度。 关键步骤解析&#xff1a; 1. 极线端点计算&#xff1a; const BearingVector A T_…

C 语言基础入门:基本数据类型与运算符详解

一、基本数据类型C 语言提供了丰富的基本数据类型&#xff0c;用于存储不同类型的数据&#xff0c;主要包括整数类型、浮点类型和布尔类型。1. 整数类型整数类型用于存储整数&#xff0c;根据是否带符号以及占用存储空间的不同&#xff0c;可进一步细分&#xff1a;类型名占用存…

应用在核电行业的虚拟现实解决方案

核能领域正处于创新与责任的交汇点。尽管核反应堆提供了高效且可持续的能源&#xff0c;但由于放射性物质的危险性&#xff0c;其也带来了独特挑战。虚拟现实&#xff08;VR&#xff09;技术正通过为远程操作、应急响应和放射性物质处理提供先进解决方案&#xff0c;彻底革新这…

CTF Web的数组巧用

PHP数组绕过intval和preg_match的CTF技巧 原题目 <?php include("flag.php"); // 引入flag文件&#xff0c;flag变量在这里定义 show_source("index.php"); // 显示index.php文件的源码&#xff08;方便选手查看&#xff09;// 判断是否通过GET方式传入…

vue2+elementui使用compressorjs压缩上传的图片

首先是npm install compressorjs 然后新建一个compressorjs.js的文件 import Compressor from "compressorjs";// 默认压缩配置 const DEFAULT_COMPRESS_OPTIONS {quality: 0.6, // 默认压缩质量 (0-1)maxWidth: 1920, // 最大宽度maxHeight: 1080, // 最大高度con…

GPIO详解:不仅仅是输入输出那么简单

GPIO详解&#xff1a;不仅仅是输入输出那么简单 “别小看一个小小的引脚&#xff0c;它可是 MCU 世界的社交之门。” &#x1f44b; 先打个招呼&#xff1a;什么是 GPIO&#xff1f; GPIO&#xff0c;全称是 General Purpose Input/Output —— 通用输入输出口。 简单说&…

深度学习5(深层神经网络 + 参数和超参数)

深层神经网络简介 深层神经网络是机器学习中一种重要的模型&#xff0c;它通过增加网络的“深度”&#xff08;即隐藏层的数量&#xff09;来提升模型对复杂数据的表示和学习能力。同浅层类似&#xff0c;也分为三个部分&#xff1a; 输入层&#xff1a;接收原始数据&#xff…