当前位置: 首页 > news >正文

深度剖析八大排序算法

         欢迎并且感谢大家指出我的问题,由于本人水平有限,有些内容写的不是很全面,只是把比较实用的东西给写下来,如果有写的不对的地方,还希望各路大牛多多指教!谢谢大家!🥰

        在计算机科学领域,排序算法是基础且重要的算法类别,它能够将一组无序的数据按照特定的顺序(如升序或降序)重新排列。接下来,我们将详细探讨冒泡排序、选择排序、插入排序、希尔排序、快速排序、归并排序、堆排序和计数排序这八大排序算法。

冒泡排序

基本概念

冒泡排序是一种简单的比较排序算法,它通过多次比较相邻元素并交换位置,将最大(或最小)的元素逐步 “冒泡” 到数组的末尾。

核心思想

重复地走访要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。

算法步骤

  1. 比较相邻的元素。如果第一个比第二个大(升序),就交换它们两个。
  1. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
  1. 针对所有的元素重复以上的步骤,除了最后一个。
  1. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

代码实现(Java)

public class BubbleSort {public static void bubbleSort(int[] arr) {int n = arr.length;for (int i = 0; i < n - 1; i++) {for (int j = 0; j < n - i - 1; j++) {if (arr[j] > arr[j + 1]) {int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}}
}

优缺点及适用场景

  • 优点:实现简单,代码量少,比较稳定(相同元素的相对顺序在排序前后不会改变)。
  • 缺点:时间复杂度较高,为 O (n²),在数据量较大时效率较低。
  • 适用场景:适用于数据量较小且对稳定性有要求的场景。

选择排序

基本概念

选择排序是一种简单直观的排序算法,它在每一趟选择未排序序列中最小(或最大)的元素,存放到已排序序列的末尾。

核心思想

首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

算法步骤

  1. 初始状态:无序区为整个数组,有序区为空。
  1. 第 1 趟排序:在无序区中选出最小(大)的元素,将它与无序区的第 1 个元素交换,此时有序区增加 1 个元素,无序区减少 1 个元素。
  1. 重复第 2 步,直到无序区为空。

代码实现(Java)

public class SelectionSort {public static void selectionSort(int[] arr) {int n = arr.length;for (int i = 0; i < n - 1; i++) {int minIndex = i;for (int j = i + 1; j < n; j++) {if (arr[j] < arr[minIndex]) {minIndex = j;}}int temp = arr[minIndex];arr[minIndex] = arr[i];arr[i] = temp;}}
}

优缺点及适用场景

  • 优点:简单直观,无论什么数据进去都是 O (n²) 的时间复杂度,所以如果数据规模较小,可以考虑使用。
  • 缺点:时间复杂度高,同样为 O (n²),且不稳定。
  • 适用场景:适用于数据量较小,对时间复杂度要求不高,且对稳定性没有要求的场景。

插入排序

基本概念

插入排序是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据。

核心思想

把 n 个待排序的元素看成一个有序表和一个无序表。开始时有序表中只包含 1 个元素,无序表中包含 n - 1 个元素;排序过程中每次从无序表中取出第一个元素,将它插入到有序表中的适当位置,使之成为新的有序表,重复 n - 1 次可完成排序过程。

算法步骤

  1. 从第一个元素开始,该元素可以认为已经被排序。
  1. 取出下一个元素,在已经排序的元素序列中从后向前扫描。
  1. 如果已排序元素大于新元素,将已排序元素移到下一位置。
  1. 重复步骤 3,直到找到已排序的元素小于或者等于新元素的位置。
  1. 将新元素插入到该位置后。
  1. 重复步骤 2~5。

代码实现(Java)

public class InsertionSort {public static void insertionSort(int[] arr) {int n = arr.length;for (int i = 1; i < n; i++) {int key = arr[i];int j = i - 1;while (j >= 0 && arr[j] > key) {arr[j + 1] = arr[j];j = j - 1;}arr[j + 1] = key;}}
}

优缺点及适用场景

  • 优点:在数据量较小或者部分有序的情况下,效率较高,并且是稳定的排序算法。
  • 缺点:时间复杂度在最坏情况下为 O (n²),不适用于大规模数据排序。
  • 适用场景:适用于数据量较小、部分有序的数据排序,以及对稳定性有要求的场景。

希尔排序

基本概念

希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。它通过将原始数据分成多个子序列,对每个子序列进行插入排序,逐步减少增量,最终使整个序列有序。

核心思想

先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录 “基本有序” 时,再对全体记录进行依次直接插入排序。

算法步骤

  1. 选择一个增量序列 t1,t2,…,tk,其中 ti > tj, tk = 1。
  1. 按增量序列个数 k,对序列进行 k 趟排序。
  1. 每趟排序,根据对应的增量 ti,将待排序列分割成若干长度为 m 的子序列,分别对各子表进行直接插入排序。仅增量因子为 1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。

代码实现(Java)

public class ShellSort {public static void shellSort(int[] arr) {int n = arr.length;for (int gap = n / 2; gap > 0; gap /= 2) {for (int i = gap; i < n; i++) {int temp = arr[i];int j;for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) {arr[j] = arr[j - gap];}arr[j] = temp;}}}
}

优缺点及适用场景

  • 优点:希尔排序的时间复杂度比 O (n²) 要好很多,在中等规模数据下表现良好,并且实现相对简单。
  • 缺点:希尔排序是不稳定的排序算法,并且其时间复杂度分析较为复杂。
  • 适用场景:适用于中等规模数据的排序,对稳定性要求不高的场景。

快速排序

基本概念

快速排序是一种分治的排序算法,它通过选择一个基准元素,将数组分为两部分,使得左边部分的元素都小于基准元素,右边部分的元素都大于基准元素,然后递归地对左右两部分进行排序。

核心思想

  1. 从数列中挑出一个基准值(通常选择第一个元素或最后一个元素)。
  1. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区操作。
  1. 递归地把小于基准值元素的子数列和大于基准值元素的子数列排序。

算法步骤

  1. 选择基准值 pivot。
  1. 初始化两个指针 left 和 right,left 指向数组的起始位置,right 指向数组的末尾位置。
  1. 从 right 开始,向左移动 right 指针,直到找到一个小于 pivot 的元素;从 left 开始,向右移动 left 指针,直到找到一个大于 pivot 的元素。
  1. 如果 left < right,交换这两个元素,然后继续步骤 3。
  1. 当 left >= right 时,将 pivot 与 left 指向的元素交换,此时 pivot 左边的元素都小于它,右边的元素都大于它。
  1. 递归地对 pivot 左边和右边的子数组进行快速排序。

代码实现(Java)

public class QuickSort {public static void quickSort(int[] arr, int low, int high) {if (low < high) {int pi = partition(arr, low, high);quickSort(arr, low, pi - 1);quickSort(arr, pi + 1, high);}}private static int partition(int[] arr, int low, int high) {int pivot = arr[high];int i = (low - 1);for (int j = low; j < high; j++) {if (arr[j] < pivot) {i++;int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}int temp = arr[i + 1];arr[i + 1] = arr[high];arr[high] = temp;return i + 1;}
}

优缺点及适用场景

  • 优点:平均时间复杂度为 O (nlogn),在大多数情况下表现非常高效,并且是一种原地排序算法(不需要额外的大量辅助空间)。
  • 缺点:在最坏情况下(如数组已经有序),时间复杂度会退化为 O (n²),并且快速排序是不稳定的排序算法。
  • 适用场景:适用于大规模数据的排序,对稳定性没有要求的场景。

归并排序

基本概念

归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。它将一个数组分成两个子数组,对每个子数组进行排序,然后将排序好的子数组合并成一个最终的有序数组。

核心思想

  1. 把长度为 n 的输入序列分成两个长度为 n/2 的子序列。
  1. 对这两个子序列分别采用归并排序。
  1. 将两个排序好的子序列合并成一个最终的有序序列。

算法步骤

  1. 分解:将数组不断地分成两个子数组,直到子数组的长度为 1。
  1. 合并:将两个有序的子数组合并成一个更大的有序数组。合并时,比较两个子数组的元素,将较小的元素依次放入一个临时数组中,直到其中一个子数组的元素全部放入临时数组,然后将另一个子数组的剩余元素也放入临时数组。
  1. 将临时数组中的元素复制回原数组,完成一次合并。
  1. 重复步骤 2 和 3,直到所有子数组都合并成一个有序数组。

代码实现(Java)

public class MergeSort {public static void mergeSort(int[] arr) {int n = arr.length;if (n < 2) {return;}int mid = n / 2;int[] left = new int[mid];int[] right = new int[n - mid];System.arraycopy(arr, 0, left, 0, mid);System.arraycopy(arr, mid, right, 0, n - mid);mergeSort(left);mergeSort(right);merge(arr, left, right);}private static void merge(int[] arr, int[] left, int[] right) {int i = 0, j = 0, k = 0;while (i < left.length && j < right.length) {if (left[i] < right[j]) {arr[k] = left[i];i++;} else {arr[k] = right[j];j++;}k++;}while (i < left.length) {arr[k] = left[i];i++;k++;}while (j < right.length) {arr[k] = right[j];j++;k++;}}
}

优缺点及适用场景

  • 优点:时间复杂度始终为 O (nlogn),并且是稳定的排序算法,适用于大规模数据的排序。
  • 缺点:需要额外的空间来存储临时数组,空间复杂度为 O (n)。
  • 适用场景:适用于对稳定性有要求,数据量较大的场景,如外部排序。

堆排序

基本概念

堆排序是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。

核心思想

  1. 首先将待排序的数组构建成一个最大堆(升序排序时)或最小堆(降序排序时)。
  1. 然后将堆顶元素与堆的最后一个元素交换,此时堆的最后一个元素就是最大(或最小)的元素,将其从堆中移除(实际上是缩小堆的范围)。
  1. 对剩余的元素重新调整为最大堆(或最小堆),重复步骤 2,直到堆中只剩下一个元素,此时数组已经有序。

算法步骤

  1. 初始化堆:将数组构建成一个最大堆(或最小堆)。从最后一个非叶子节点开始,依次对每个非叶子节点进行向下调整操作,使其满足堆的性质。
  1. 交换与调整:将堆顶元素与堆的最后一个元素交换,然后对堆顶元素进行向下调整操作,使堆重新满足堆的性质。
  1. 重复步骤 2,直到堆中只剩下一个元素。

代码实现(Java)

public class HeapSort {public static void heapSort(int[] arr) {int n = arr.length;// 构建最大堆for (int i = n / 2 - 1; i >= 0; i--) {heapify(arr, n, i);}// 一个个取出元素for (int i = n - 1; i > 0; i--) {int temp = arr[0];arr[0] = arr[i];arr[i] = temp;// 调整堆heapify(arr, i, 0);}}private static void heapify(int[] arr, int n, int i) {int largest = i;int left = 2 * i + 1;int right = 2 * i + 2;if (left < n && arr[left] > arr[largest]) {largest = left;}if (right < n && arr[right] > arr[largest]) {largest = right;}if (largest!= i) {int swap = arr[i];arr[i] = arr[largest];arr[largest] = swap;// 递归调整受影响的子树heapify(arr, n, largest);}}
}

优缺点及适用场景

  • 优点:时间复杂度为 O (nlogn),并且是原地排序算法,不需要额外的大量辅助空间。
  • 缺点:堆排序是不稳定的排序算法,并且实现相对复杂。
  • 适用场景:适用于大规模数据的排序,对稳定性没有要求,并且空间有限的场景。

计数排序

基本概念

计数排序是一种非比较排序算法,它通过统计每个元素在数组中出现的次数,然后根据统计结果将元素按照顺序输出,从而实现排序。

核心思想

        1.找出待排序数组中的最大值和最小值,确定计数数组的范围。

        2.统计每个元素在数组中出现的次数,将统计结果存储在计数数组中。

        3.根据计数数组,将每个元素按照出现的次数依次输出到结果数组中。

算法步骤

  1. 确定范围:遍历待排序数组,找出其中的最大值max和最小值min,计算出计数数组的长度countLength = max - min + 1。
  2. 初始化计数数组:创建一个长度为countLength的计数数组count,并将所有元素初始化为 0。
  3. 统计元素出现次数:再次遍历待排序数组,对于数组中的每个元素num,将count[num - min]的值加 1,表示该元素出现的次数。
  4. 计算前缀和:对计数数组进行处理,计算每个元素的前缀和。即从计数数组的第二个元素开始,每个元素都加上前一个元素的值。这一步的目的是让count[i]表示小于等于i + min的元素个数。
  5. 填充结果数组:创建一个与待排序数组长度相同的结果数组result。从待排序数组的末尾开始遍历,对于每个元素num,根据count[num - min]的值确定其在结果数组中的位置,然后将count[num - min]减 1。重复此步骤,直到所有元素都放入结果数组中。

代码实现

  1. public class CountingSort {public static void countingSort(int[] arr) {if (arr == null || arr.length == 0) {return;}int max = arr[0];int min = arr[0];// 找出最大值和最小值for (int num : arr) {if (num > max) {max = num;}if (num < min) {min = num;}}int countLength = max - min + 1;int[] count = new int[countLength];// 统计每个元素出现的次数for (int num : arr) {count[num - min]++;}// 计算前缀和for (int i = 1; i < countLength; i++) {count[i] += count[i - 1];}int[] result = new int[arr.length];// 填充结果数组for (int i = arr.length - 1; i >= 0; i--) {result[count[arr[i] - min] - 1] = arr[i];count[arr[i] - min]--;}// 将结果复制回原数组System.arraycopy(result, 0, arr, 0, arr.length);}
    }

    优缺点及适用场景

  2. 优点:时间复杂度为 O (n + k),其中 n 是待排序数组的长度,k 是数据的范围。在数据范围不大且数据量较大时,效率非常高。并且计数排序是稳定的排序算法。
  3. 缺点:对数据的要求比较苛刻,只能用于数据范围较小且数据为整数的情况。同时,需要额外的空间来存储计数数组,空间复杂度为 O (k) 。
  4. 适用场景:适用于数据范围有限,且对稳定性有要求的场景,比如对学生成绩(分数范围固定)进行排序等。

相关文章:

深度剖析八大排序算法

欢迎并且感谢大家指出我的问题&#xff0c;由于本人水平有限&#xff0c;有些内容写的不是很全面&#xff0c;只是把比较实用的东西给写下来&#xff0c;如果有写的不对的地方&#xff0c;还希望各路大牛多多指教&#xff01;谢谢大家&#xff01;&#x1f970; 在计算机科学领…...

JVM_程序计数器的作用、特点、线程私有、本地方法的概述

①. 程序计数器 ①. 作用 (是用来存储指向下一条指令的地址,也即将要执行的指令代码。由执行引擎读取下一条指令) ②. 特点(是线程私有的 、不会存在内存溢出) ③. 注意:在物理上实现程序计数器是在寄存器实现的,整个cpu中最快的一个执行单元 ④. 它是唯一一个在java虚拟机规…...

【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】2.20 傅里叶变换:从时域到频域的算法实现

2.20 傅里叶变换&#xff1a;从时域到频域的算法实现 目录 #mermaid-svg-zrRqIme9IEqP6JJE {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-zrRqIme9IEqP6JJE .error-icon{fill:#552222;}#mermaid-svg-zrRqIme9IEqP…...

PAT甲级1052、Linked LIst Sorting

题目 A linked list consists of a series of structures, which are not necessarily adjacent in memory. We assume that each structure contains an integer key and a Next pointer to the next structure. Now given a linked list, you are supposed to sort the stru…...

git error: invalid path

git clone GitHub - guanpengchn/awesome-books: :books: 开发者推荐阅读的书籍 在windows上想把这个仓库拉取下来&#xff0c;发现本地git仓库创建 但只有一个.git隐藏文件夹&#xff0c;其他文件都处于删除状态。 问题&#xff1a; Cloning into awesome-books... remote:…...

优选算法合集————双指针(专题二)

好久都没给大家带来算法专题啦&#xff0c;今天给大家带来滑动窗口专题的训练 题目一&#xff1a;长度最小的子数组 题目描述&#xff1a; 给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl1, …...

Ubuntu下Tkinter绑定数字小键盘上的回车键(PySide6类似)

设计了一个tkinter程序&#xff0c;在Win下绑定回车键&#xff0c;直接绑定"<Return>"就可以使用主键盘和小键盘的回车键直接“提交”&#xff0c;到了ubuntu下就不行了。经过搜索&#xff0c;发现ubuntu下主键盘和数字小键盘的回车键&#xff0c;名称不一样。…...

使用arcpy列表函数

本节将以ListFeatureClasses()为例,学习如何使用arcpy中的列表函数. 操作方法: 1.打开IDLE,新建脚本窗口 2.导入arcpy模块 3.设置工作空间 arcpy.env.workspace "<>" 4.调用ListFeatureClasses()函数,并将返回的值赋值给fcList变量 fcList arcpy.ListFe…...

基于联合概率密度与深度优化的反潜航空深弹命中概率模型研究摘要

前言:项目题材来自数学建模2024年的D题,文章内容为笔者和队友原创,提供一个思路。 摘要 随着现代军事技术的发展,深水炸弹在特定场景下的反潜作战效能日益凸显,如何最大化的发挥深弹威力也成为重要研究课题。本文针对评估深弹投掷落点对命中潜艇概率的影响进行分析,综合利…...

【PyQt】pyqt小案例实现简易文本编辑器

pyqt小案例实现简易文本编辑器 分析 实现了一个简单的文本编辑器&#xff0c;使用PyQt5框架构建。以下是代码的主要功能和特点&#xff1a; 主窗口类 (MyWindow): 继承自 QWidget 类。使用 .ui 文件加载用户界面布局。设置窗口标题、状态栏消息等。创建菜单栏及其子菜单项&…...

二叉树03(数据结构初阶)

文章目录 一&#xff1a;实现链式结构二叉树1.1前中后序遍历1.1.1遍历规则1.1.2代码实现 1.2结点个数以及高度等1.2.1二叉树结点个数1.2.2二叉树叶子结点个数1.2.3二叉树第k层结点个数1.2.4二叉树的深度/高度1.2.5 二叉树查找值为x的结点1.2.6二叉树的销毁 1.3层序遍历1.4判断是…...

ComfyUI工作流 图像反推生成人像手办人像参考(SDXL版)

文章目录 图像反推生成人像手办人像参考SD模型Node节点工作流程效果展示开发与应用图像反推生成人像手办人像参考 本工作流旨在通过利用 Stable Diffusion XL(SDXL)模型和相关辅助节点,实现高效的人像参考生成和手办设计。用户可通过加载定制的模型、LORA 调整和控制节点对…...

【01】共识机制

BTF共识 拜占庭将军问题 拜占庭将军问题是一个共识问题 起源 Leslie Lamport在论文《The Byzantine Generals Problem》提出拜占庭将军问题。 核心描述 军中可能有叛徒&#xff0c;却要保证进攻一致&#xff0c;由此引申到计算领域&#xff0c;发展成了一种容错理论。随着…...

sentinel的限流原理

Sentinel 的限流原理基于 流量统计 和 流量控制策略&#xff0c;通过动态规则对系统资源进行保护。其核心设计包括以下几个关键点&#xff1a; 流量统计模型&#xff1a;滑动时间窗口 Sentinel 使用 滑动时间窗口算法 统计单位时间内的请求量&#xff0c;相比传统的固定时间窗…...

ZOJ 1007 Numerical Summation of a Series

原题目链接 生成该系列值的表格 对于x 的 2001 个值&#xff0c;x 0.000、0.001、0.002、…、2.000。表中的所有条目的绝对误差必须小于 0.5e-12&#xff08;精度为 12 位&#xff09;。此问题基于 Hamming (1962) 的一个问题&#xff0c;当时的大型机按今天的微型计算机标准来…...

『 C 』 `##` 在 C 语言宏定义中的作用解析

文章目录 ## 运算符的基本概念可变参数宏与 ## 的应用可变参数宏简介## 处理可变参数的两种情况可变参数列表为空可变参数列表不为空 示例代码验证 在 C 和 C 编程里&#xff0c;宏定义是个很有用的工具。今天咱们就来聊聊 ## 这个预处理器连接运算符在宏定义中的作用&#xff…...

独立成分分析 (ICA):用于信号分离或降维

人工智能例子汇总&#xff1a;AI常见的算法和例子-CSDN博客 独立成分分析 (Independent Component Analysis, ICA) 是一种用于信号分离和降维的统计方法&#xff0c;常用于盲源分离 (Blind Source Separation, BSS) 问题&#xff0c;例如音频信号分离或脑电信号 (EEG) 处理。…...

为什么会有函数调用参数带标签的写法?Swift函数调用的参数传递需要加前缀是否是冗余?函数调用?函数参数?

为什么会有函数调用参数带标签的写法? ObjC函数参数形式与众不同&#xff0c;实参前会加前缀&#xff0c;尤其参数很多的情况&#xff0c;可读性很强。例如&#xff1a; [person setAge: 29 setSex:1 setClass: 35]; 这种参数前面加前缀描述也被叫标签(Label). 注意&#xff0…...

实际操作 检测缺陷刀片

号he 找到目标图像的缺陷位置&#xff0c;首先思路为对图像进行预处理&#xff0c;灰度-二值化-针对图像进行轮廓分析 //定义结构元素 Mat se getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1)); morphologyEx(thre, tc, MORPH_OPEN, se, Point(-1, -1), 1); …...

使用Pygame制作“青蛙过河”游戏

本篇博客将演示如何使用 Python Pygame 从零开始编写一款 Frogger 风格的小游戏。Frogger 是一款早期街机经典&#xff0c;玩家需要帮助青蛙穿越车水马龙的马路到达对岸。本示例提供了一个精简原型&#xff0c;包含角色移动、汽车生成与移动、碰撞检测、胜利条件等关键点。希望…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度​

一、引言&#xff1a;多云环境的技术复杂性本质​​ 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时&#xff0c;​​基础设施的技术债呈现指数级积累​​。网络连接、身份认证、成本管理这三大核心挑战相互嵌套&#xff1a;跨云网络构建数据…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动

一、前言说明 在2011版本的gb28181协议中&#xff0c;拉取视频流只要求udp方式&#xff0c;从2016开始要求新增支持tcp被动和tcp主动两种方式&#xff0c;udp理论上会丢包的&#xff0c;所以实际使用过程可能会出现画面花屏的情况&#xff0c;而tcp肯定不丢包&#xff0c;起码…...

(二)原型模式

原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

12.找到字符串中所有字母异位词

&#x1f9e0; 题目解析 题目描述&#xff1a; 给定两个字符串 s 和 p&#xff0c;找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义&#xff1a; 若两个字符串包含的字符种类和出现次数完全相同&#xff0c;顺序无所谓&#xff0c;则互为…...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

基于matlab策略迭代和值迭代法的动态规划

经典的基于策略迭代和值迭代法的动态规划matlab代码&#xff0c;实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...