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

详解排序算法

文章目录

  • 1. 排序算法分类
  • 2. 比较排序算法介绍
    • 2.1 插入排序
      • 2.1.1 直接插入排序
      • 2.1.2 希尔排序
    • 2.2 选择排序
      • 2.2.1 直接选择排序
      • 2.2.2 堆排序
        • 2.2.2.1 向下调整算法建堆
        • 2.2.2.2 向上调整算法建堆
        • 2.2.2.3 进行堆排序
        • 2.2.2.4 堆排序时间、空间复杂度分析
        • 2.2.2.5 利用堆排序解决TOP-K问题
    • 2.3 比较排序
      • 2.3.1 冒泡排序
      • 2.3.2 快速排序
        • 2.3.2.1 快速排序的递归实现
        • 2.3.2.2 快速排序的非递归实现
    • 2.4 归并排序
      • 2.4.1 归并排序的递归版本
      • 2.4.3 归并排序的非递归版本
  • 3. 非比较排序

1. 排序算法分类

排序算法分为两大类:比较排序与非比较排序。

非比较排序,即计数排序。

比较排序又分为四类:

  • 插入排序:直接插入排序和希尔排序
  • 选择排序:直接选择排序和堆排序
  • 交换排序:冒泡排序和快速排序
  • 归并排序: 归并排序

2. 比较排序算法介绍

2.1 插入排序

2.1.1 直接插入排序

基本思想:直接插入排序是将一个待排序的数插入到一个已经有序的序列中,得到一个新的有序序列。平时玩扑克牌,整理手牌时,就使用了直接插入排序。

直接插入排序的代码实现:

	void InsertSrot(int* arr, int size){for (int i = 0; i < size - 1; i++){int pos = i, tmp = arr[pos + 1];while (pos >= 0){if (arr[pos] > tmp){arr[pos + 1] = arr[pos];pos--;}elsebreak;}arr[pos + 1] = tmp;}}

直接插入排序时间与空间复杂度:

  • 时间复杂度:时间复杂度为O(n ^ 2),但排序数组越趋近于有序,时间复杂度会越低,趋近于O(n)
  • 空间复杂度:只利用了常数个临时变量,空间复杂度为O(1)

2.1.2 希尔排序

希尔排序,又称为缩小增量法,其实质就是利用一个gap,进行分组的直接插入排序,然后gap不断缩小(即缩小增量),直至gap为1时,进行最后一次gap = 1的直接插入排序,即得有序序列。

讲得通俗些,希尔排序是直接插入排序改进而来的,gap不为1时,所作的排序可以视作预排序,这些预排序都是为了最后一次gap = 1的直接插入排序做准备——使得进行最后一次直接插入排序的序列趋近于有序,这样可以降低直接插入排序的时间复杂度。

希尔排序的代码实现:

void ShellSort(int* arr, int size)
{int gap = size;while (gap > 1){gap = gap / 3 + 1;for (int i = 0; i < size - gap; i++){int pos = i;int tmp = arr[pos + gap];while (pos >= 0){if (arr[pos] > tmp){arr[pos + gap] = arr[pos];pos -= gap;}elsebreak;}arr[pos + gap] = tmp;}}
}

希尔排序中gap如何缩小是有讲究的。我在上述代码中采用的缩小方式是除3加1(一定要加1,确保进行的最后一次希尔排序为gap=1的直接插入排序),这也是被普遍采用的一种缩小方式。

希尔排序的时间复杂度与空间复杂度:

  • 时间复杂度:由于gap取值的变化性,希尔排序的时间复杂度是不固定的,很难进行准确计算。因此,我们再此不做过多解释,可以将希尔排序的时间复杂度简单理解为O(n ^ 1.3)。但就整体而言,希尔排序的时间复杂度优于直接插入排序。
  • 空间复杂度:O(1)

2.2 选择排序

2.2.1 直接选择排序

直接选择排序的思想比较简单:在一个给定的序列中,找到最大值和最小值,然后把最大值放在这个序列末尾,最小值放在序列开头(如果排升序),然后这个序列在两边同时缩进一个,得到一个新的序列,再重复上述操作,直至序列长度为1时结束。

直接选择排序的代码如下:

	void SelectSort(int* arr, int n){int begin = 0, end = n - 1;while (begin < end){int max = begin, min = begin;for (int i = begin; i <= end; i++){if (arr[i] > arr[max])max = i;if (arr[i] < arr[min])min = i;}if (begin == max)max = min;swap(arr[begin++], arr[min]);swap(arr[end--], arr[max]);}}

2.2.2 堆排序

在了解堆排序之前,我们必须清楚什么是堆。
堆具备如下性质:

  • 堆是一棵完全二叉树
  • 堆中某个结点的值总是不大于或不小于其父结点的值。因此,我们可得两类堆——根结点最大的堆,我们称为最大堆或大根堆,根结点最小的堆,我们称之为最小堆或小根堆。

对于堆,或者说对于完全二叉树,我们使用数组来存储,有以下存储规则。

  • 对于具有n个结点的完全二叉树,如果按照从上至下,从左至右的数组顺序堆所有结点从0开始进行编号,则序号为i的结点有:
  1. 若i > 0 , i 位置父结点的序号为(i - 1)/ 2;i = 0时,为根结点,无父节点
  2. 若2i + 1 < n,则左孩子序号为2i + 1. 2i + 1 >= n,无左孩子
  3. 若2i + 2 < n,则右孩子序号为2i + 2, 2i + 2 >= n,无右孩子
2.2.2.1 向下调整算法建堆

既然要进行堆排序,我们肯定要先获取一个有效堆。统一起见,接下来我们都建大堆。

向下调整算法建堆代码如下所示:

	void AdjustDown(int* arr, int parent, int n){int child = parent * 2 + 1;//左孩子结点while (child < n){if (child + 1 < n && arr[child] < arr[child + 1])child++;if (arr[child] > arr[parent]){swap(arr[child], arr[parent]);parent = child;child = parent * 2 + 1;}elsebreak;}}
2.2.2.2 向上调整算法建堆

向上调整算法建堆的代码如下所示:

	void AdjustUp(int* arr, int child){int parent = (child - 1) / 2;//child结点的parent结点while (child > 0){if (arr[child] > arr[parent]){swap(arr[child], arr[parent]);child = parent;parent = (child - 1) / 2;}elsebreak;}}
2.2.2.3 进行堆排序

在获取有效堆之后,我们便可以开始堆排序。需要注意的是,堆只是保证了父结点与子结点之间的大小关系,并不保证整个数组是有序的,所以我们需要进一步处理。但堆有什么特殊性质呢?我们知道,大堆的根结点是最大的,小堆的根结点是最小的。

因此,我们利用这个性质,可以像堆弹出根结点一样,先把根结点所存储的数值与数组中最后一个子结点存储的数值进行交换,这样整个数组中最大的数(最小的数)就到了其所应到的位置上。然后,我们数组的大小减去1,即把此时的最后一个元素排除在外,之后再使用向下调整算法获得一个有效堆,再重复上述过程,直至数组中待处理的元素个数为1时,终止循环。

具体的代码如下所示:

	//堆排序void HeapSort(int* arr, int n){//向下调整算法建堆for (int i = (n - 2) / 2; i >= 0; i--)AdjustDown(arr, i, n);//向上调整算法建堆for (int i = 1; i < n; i++)AdjustUp(arr, i);//两种建堆方式,选择一种即可//已建立有效堆,进行堆排序int size = n;while (size > 1){swap(arr[0], arr[size - 1]);size--;AdjustDown(arr, 0, size);}}
2.2.2.4 堆排序时间、空间复杂度分析

堆排序的时间复杂度需要分为两种情况来讨论:向上调整算法建堆和向下调整算法建堆。

当使用向上调整算法建堆时,此调整算法的时间复杂度为O(n * log n)。
当使用向下调整算法建堆时,此调整算法的时间复杂度为O(n)。

而对于已经建立的有效堆,进行实际堆排序时,即上述代码第二个循环的时间复杂度为O(n * log n),与向上调整算法建堆的时间复杂度相同。

所以,将两个循环叠加,综合来看的话,堆排序的时间复杂度为O(n * log n)。但需要注意的是,实际上堆排序中使用向下调整算法建堆会优于使用向上调整算法建堆,所以堆排序中使用向下调整算法建堆会更普遍一些。

堆排序的空间复杂度显然为O(1)。

2.2.2.5 利用堆排序解决TOP-K问题

TOP-K问题在现实生活中是非常常见的,比如游戏中最活跃的10名玩家,一个公司中绩效最高的10个人。对于数据量不是很大的TOP-K问题,可以直接创建数组存储,然后直接排序。但现实中,数据量是非常大,内存中是存不下的,这种时候我们只能将这些数据放在文件中,在这种情况下,我们该如何解决TOP-K问题呢?

我们使用堆排序来解决。具体步骤如下:

  1. 先从所有数据中读取K个数据到内存中,存储在数组中。
  2. 对数组进行向下调整算法建堆(向上调整算法建堆),获得一个有效堆,此时堆的根结点就是整个堆的最大值(最小值)。
  3. 继续逐个从文件中读取数据,并与堆的根结点所对应数据比较,满足条件(大于或小于)即令此数据为堆的根结点。
  4. 向下调整算法建堆,之后不断重复步骤3和4,直至文件中的数据被读取完毕。此时,数组中的数据即为所要求得的TOP-K。

2.3 比较排序

2.3.1 冒泡排序

冒泡排序较为简单,时间复杂度为O(n ^ 2),此处不做解释,具体看代码:

	void BubbleSort(int* arr, int n){for (int i = 0; i < n - 1; i++){int flag = 1;for (int j = 0; j < n - 1 - i; j++){if (arr[j] > arr[j + 1]){swap(arr[j], arr[j + 1]);flag = 0;}}if (flag)break;}}

2.3.2 快速排序

快速排序的核心思想在于,在待排序的序列中选定一个基准值,然后通过一次快排,使得整个序列能够分为两个部分,一部分的值满足小于等于此基准值,另一部分的值满足大于等于此基准值,这是一次快排达到的效果。快速排序有递归与非递归之分。

2.3.2.1 快速排序的递归实现

快速排序的递归实现有很多种版本,如hoare版本,挖坑法以及lumuto的前后双指针快排,而对于快排基准值的选择也有很多,如取序列的开头或结尾,又或是中间数,或者随机取基准值。不同的版本下,再考虑到基准值所选取的不同,快排的具体写法是有差异的,但核心思想是不变的,最难处理的主要快排的边界问题,边界问题处理不好,快排就很容易陷入快排错误,或者死递归中。

以下对快排的递归实现不详细介绍,而是展示一个使用hoare快排的通用模板:

	void QuickSort(int* arr, int l, int r){if (l >= r)return;int i = l - 1, j = r + 1, x = arr[(l + r) >> 1];while (i < j){do i++; while (arr[i] < x);do j--; while (arr[j] > x);if (i < j)swap(arr[i], arr[j]);}QuickSort(arr, l, j);QuickSort(arr, j + 1, r);}
2.3.2.2 快速排序的非递归实现

快速排序的非递归实现要借助数据结构
本质上,因为是非递归实现,借助栈实际上是为了将一轮快排后,得到的左右子序列的边界存储起来,用于进行之后的快排,如此往复,直至栈为空,此时快排结束。

代码示例如下所示:

void QuickSort(int* arr,int l,int r)
{stack<int> st;if(l < r)st.push(r),st.push(l);while(!st.empty()){l = st.top(),st.pop();r = st.top(),st.pop();int i = l - 1,j = r + 1,x = arr[(l + r) >> 1];while(i < j){do i++;while(arr[i] < x);do j--;while(arr[j] > x);if(i < j)swap(arr[i],arr[j]);}//先排左序列,再排右序列if(j + 1 < r)st.push(r),st.push(j + 1);if(l < j)st.push(j),st.push(l);}
}

2.4 归并排序

2.4.1 归并排序的递归版本

归并排序是一种利用递归思想的排序算法,它的基本流程如下:

  1. 先对数组不断二分递归,直至划分出的每个小组别元素的个数为1,由此得到最小的有序序列
  2. 然后再对这些有序的序列,通过有序序列的合并方法,两两不断合并,直至合并出原数组大小的有序序列

归并排序的时间复杂度为O(n * log n),但由于需要创建一个临时数组用于存储归并出的有序序列,因此归并排序的空间复杂度为O(n)。

具体代码如下所示:

	void MergeSort(int* arr, int left,int right){if (left >= right)return;int mid = (left + right) >> 1;MergeSort(arr, left, mid);MergeSort(arr, mid + 1, right);int i = left, j = mid + 1;vector<int> tmp;while (i <= mid && j <= right){if (arr[i] <= arr[j])tmp.push_back(arr[i++]);elsetmp.push_back(arr[j++]);}while (i <= mid)tmp.push_back(arr[i++]);while (j <= right)tmp.push_back(arr[j++]);//将tmp数组中的内容拷贝到arr数组的相应位置for (int i = left, j = 0; i <= right; i++, j++)arr[i] = tmp[j];}

在这里补充一点知识,归并排序既是内排序,也是外排序。内排序,即排序数据全部存储在内存中的排序;而外排序则是排序数据不存储在内存中的排序。讲得准确些,外排序是由于排序数据量过大,导致这些数据无法全部读入内存中,因此将其存储在内存之外,比如硬盘的文件中。对于这种存储在硬盘文件上的数据,无法一次性拿到所有数据,只能读部分数据,再排这部分数据,如此循环。而归并排序的有序序列归并的思想是可以用于外排序的,因此归并排序可以用于给存储在文件中数量无比庞大的数据进行外排序。

2.4.3 归并排序的非递归版本

归并排序不用递归,使用循环来实现。

3. 非比较排序

非比较排序,即排序时不需要通过比较数据以确定数据之间的先后关系,而是通过一个计数数组以实现排序,我们将这种排序称为计数排序,又称为鸽巢原理。

具体代码如下所示:

	void CountSort(int* arr, int n){int max = arr[0], min = arr[0];for (int i = 1; i < n; i++){if (arr[i] > max)max = arr[i];if (arr[i] < min)min = arr[i];}int range = max - min + 1;vector<int> count(range, 0);for (int i = 0; i < n; i++)count[arr[i] - min]++;for (int i = 0, j = 0; i < range; i++)while (count[i]--)arr[j++] = i + min;}

计数排序的时间复杂度为O(n),空间复杂度为O(range)。

通过以上代码我们可以发现计数排序比较适用于待排序数据比较集中的情况,因为此时计数数组不用开得很大,空间复杂度不大;而若是数据很分散,计数数组需要开得比较大,甚至会出现range要远大于数据个数的情况,此时就不推荐使用计数排序。

相关文章:

详解排序算法

文章目录 1. 排序算法分类2. 比较排序算法介绍2.1 插入排序2.1.1 直接插入排序2.1.2 希尔排序 2.2 选择排序2.2.1 直接选择排序2.2.2 堆排序2.2.2.1 向下调整算法建堆2.2.2.2 向上调整算法建堆2.2.2.3 进行堆排序2.2.2.4 堆排序时间、空间复杂度分析2.2.2.5 利用堆排序解决TOP-…...

练习题 - Django 4.x File 文件上传使用示例和配置方法

在现代的 web 应用开发中,文件上传是一个常见的功能,无论是用户上传头像、上传文档,还是其他类型的文件,处理文件上传都是开发者必须掌握的技能之一。Django 作为一个流行的 Python web 框架,提供了便捷的文件上传功能和配置方法。学习如何在 Django 中实现文件上传,不仅…...

Vue 响应式渲染 - 待办事项简单实现

Vue 渐进式JavaScript 框架 基于Vue2的学习笔记 - Vue 响应式渲染 - 待办事项简单实现 目录 待办事项简单实现 页面初始化 双向绑定的指令 增加留言列表设置 增加删除按钮 最后优化 总结 待办事项简单实现 页面初始化 对页面进行vue的引入、创建输入框和按钮及实例化V…...

【福州市AOI小区面】shp数据学校大厦商场等占地范围面数据内容测评

AOI城区小区面样图和数据范围查看&#xff1a; — 字段里面有name字段。分类比较多tpye&#xff1a;每个值代表一个类型。比如字段type中1549代表小区住宅&#xff0c;1563代表学校。小区、学校等占地面积范围数据 —— 小区范围占地面积面数据shp格式 无偏移坐标&#xff0c;只…...

llama.cpp LLM_ARCH_DEEPSEEK and LLM_ARCH_DEEPSEEK2

llama.cpp LLM_ARCH_DEEPSEEK and LLM_ARCH_DEEPSEEK2 1. LLM_ARCH_DEEPSEEK and LLM_ARCH_DEEPSEEK22. LLM_ARCH_DEEPSEEK and LLM_ARCH_DEEPSEEK23. struct ggml_cgraph * build_deepseek() and struct ggml_cgraph * build_deepseek2()References 不宜吹捧中国大语言模型的同…...

k8s简介,k8s环境搭建

目录 K8s简介环境搭建和准备工作修改主机名&#xff08;所有节点&#xff09;配置静态IP&#xff08;所有节点&#xff09;关闭防火墙和seLinux&#xff0c;清除iptables规则&#xff08;所有节点&#xff09;关闭交换分区&#xff08;所有节点&#xff09;修改/etc/hosts文件&…...

2024年个人总结

序 照例&#xff0c;每年都有的个人年度总结来了&#xff0c;看了很多其他大佬的总结&#xff0c;感觉自己的2024过于单薄&#xff0c;故事也不太丰满&#xff0c;自己就回去比较&#xff0c;自己哪里做的不好 &#xff1f;但后来发现已经进入了一个思维误区。 年度总结年度总结…...

【落羽的落羽 数据结构篇】顺序表

文章目录 一、线性表二、顺序表1. 概念与分类2. 准备工作3. 静态顺序表4. 动态顺序表4.1 定义顺序表结构4.2 顺序表的初始化4.3 检查空间是否足够4.3 尾部插入数据4.4 头部插入数据4.5 尾部删除数据4.6 头部删除数据4.7 在指定位置插入数据4.8 在指定位置删除数据4.9 顺序表的销…...

麒麟操作系统服务架构保姆级教程(十四)iptables防火墙四表五链和防火墙应用案例

如果你想拥有你从未拥有过的东西&#xff0c;那么你必须去做你从未做过的事情 防火墙在运维工作中有着不可或缺的重要性。首先&#xff0c;它是保障网络安全的关键防线&#xff0c;通过设置访问控制规则&#xff0c;可精准过滤非法网络流量&#xff0c;有效阻挡外部黑客攻击、恶…...

Linux之详谈——权限管理

目录 小 峰 编 程 ​编辑 一、权限概述 1、什么是权限 2、为什么要设置权限 3、Linux中的权限类别- 4、Linux中文件所有者 1&#xff09;所有者分类&#xff08;谁&#xff09; 2&#xff09;所有者的表示方法 ① u(the user who owns it)&#xff08;属主权限&…...

第05章 13 椭球体张量可视化应用一则-神经束追踪

在神经束追踪&#xff08;Tractography&#xff09;中&#xff0c;椭球体张量&#xff08;Ellipsoid Tensor&#xff09;通常用于描述神经纤维的方向和扩散特性。这种技术广泛应用于磁共振成像&#xff08;MRI&#xff09;的扩散张量成像&#xff08;DTI&#xff09;数据中。VT…...

Celery

https://www.bilibili.com/video/BV1RGDEY5ERB 架构 简单任务 执行 包结构 本示例&#xff1a; app 添加任务 获取结果 配置延时任务 任务配置 beat 提交定时任务...

JavaScript系列(48)-- 3D渲染引擎实现详解

JavaScript 3D渲染引擎实现详解 &#x1f3ae; 今天&#xff0c;让我们深入探讨JavaScript的3D渲染引擎实现。通过WebGL和现代JavaScript技术&#xff0c;我们可以构建一个功能完整的3D渲染系统。 3D渲染基础概念 &#x1f31f; &#x1f4a1; 小知识&#xff1a;3D渲染引擎的…...

Golang并发机制及CSP并发模型

Golang 并发机制及 CSP 并发模型 Golang 是一门为并发而生的语言&#xff0c;其并发机制基于 CSP&#xff08;Communicating Sequential Processes&#xff0c;通信顺序过程&#xff09; 模型。CSP 是一种描述并发系统中交互模式的正式语言&#xff0c;强调通过通信来共享内存…...

使用 Docker + Nginx + Certbot 实现自动化管理 SSL 证书

使用 Docker Nginx Certbot 实现自动化管理 SSL 证书 在互联网安全环境日益重要的今天&#xff0c;为站点或应用部署 HTTPS 已经成为一种常态。然而&#xff0c;手动申请并续期证书既繁琐又容易出错。本文将以 Nginx Certbot 为示例&#xff0c;基于 Docker 容器来搭建一个…...

游戏策划的分类

P3游戏策划分类 1.程序2.美术3.策划 程序&#xff1a;一般分为客户端程序和服务器程序 客户端程序一般负责游戏的前端画面表现 服务器程序负责游戏的后端运算 美术&#xff1a;角色原画&#xff0c;角色模型动作&#xff0c;场景原画&#xff0c;场景模型&#xff0c;UI设计&a…...

Edge-TTS在广电系统中的语音合成技术的创新应用

Edge-TTS在广电系统中的语音合成技术的创新应用 作者&#xff1a;本人是一名县级融媒体中心的工程师&#xff0c;多年来一直坚持学习、提升自己。喜欢Python编程、人工智能、网络安全等多领域的技术。 摘要 随着人工智能技术的快速发展&#xff0c;文字转语音&#xff08;Te…...

python学opencv|读取图像(四十七)使用cv2.bitwise_not()函数实现图像按位取反运算

【0】基础定义 按位与运算&#xff1a;两个等长度二进制数上下对齐&#xff0c;全1取1&#xff0c;其余取0。按位或运算&#xff1a;两个等长度二进制数上下对齐&#xff0c;有1取1&#xff0c;其余取0。 按位取反运算&#xff1a;一个二进制数&#xff0c;0变1,1变0。 【1】…...

一文讲解Java中Object类常用的方法

在Java中&#xff0c;经常提到一个词“万物皆对象”&#xff0c;其中的“万物”指的是Java中的所有类&#xff0c;而这些类都是Object类的子类&#xff1b; Object主要提供了11个方法&#xff0c;大致可以分为六类&#xff1a; 对象比较&#xff1a; public native int has…...

【算法篇·更新中】C++秒入门(附练习用题目)

一.二分 1.二分查找 我们来看这样一道题&#xff1a; 有一个保证有序的数组a&#xff0c;它的长度为n。现在我们需要知道这个序列是否含有x。 数据范围&#xff1a;保证n<1e9 我们看到这道题之后&#xff0c;第一时间想到的就是暴力枚举了&#xff0c;可是我们发现直接枚举…...

面向对象编程 vs 面向过程编程

面向对象编程 vs 面向过程编程&#xff1a;深入解析这两种编程范式的区别 在当今软件开发领域&#xff0c;编程范式的选择对于项目的可维护性和可扩展性至关重要。面向对象编程&#xff08;OOP&#xff09;和面向过程编程&#xff08;POP&#xff09;是两种根本的编程思想。本…...

【Rust自学】16.2. 使用消息传递来跨线程传递数据

喜欢的话别忘了点赞、收藏加关注哦&#xff08;加关注即可阅读全文&#xff09;&#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵&#xff01;(&#xff65;ω&#xff65;) 16.2.1. 消息传递 有一种很流行而且能保证安全并发的技术&#xff08;或者叫机制&#xff…...

【四川乡镇界面】图层shp格式arcgis数据乡镇名称和编码2020年wgs84无偏移内容测评

本文将详细解析标题和描述中提到的IT知识点&#xff0c;主要涉及GIS&#xff08;Geographic Information System&#xff0c;地理信息系统&#xff09;技术&#xff0c;以及与之相关的文件格式和坐标系统。 我们要了解的是"shp"格式&#xff0c;这是一种广泛用于存储…...

人物传记之新月篇

相关故事链接&#xff08;及时更新&#xff09;&#xff1a;Python的那些事第四篇&#xff1a;编程中的智慧之光控制结构-CSDN博客 Python的那些事第五篇&#xff1a;数据结构的艺术与应用-CSDN博客 目录 1. C语言程序&#xff1a;增强版加密与解密工具 2. Python程序&#x…...

TypeScript中的函数:类型安全与高级特性

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…...

DDD 和 TDD

领域驱动设计&#xff08;DDD&#xff09; DDD 是一种软件开发方法&#xff0c;强调通过与领域专家的密切合作来构建一个反映业务逻辑的模型。其核心思想是将业务逻辑和技术实现紧密结合&#xff0c;以便更好地解决复杂的业务问题。 DDD 的关键概念&#xff1a; 1. 领域模型 …...

【C语言分支与循环结构详解】

目录 ---------------------------------------begin--------------------------------------- 一、分支结构 1. if语句 2. switch语句 二、循环结构 1. for循环 2. while循环 3. do-while循环 三、嵌套结构 结语 -----------------------------------------end----…...

FaceFusion

文章目录 一、关于 FaceFusion预览 二、安装三、用法 一、关于 FaceFusion FaceFusion 是行业领先的人脸操作平台 github : https://github.com/facefusion/facefusion官方文档&#xff1a;https://docs.facefusion.io/Discord : https://discord.com/invite/facefusion-1141…...

图论——单源最短路的扩展应用

acwing1137.选择最佳路线 本题有两个解决思路 1.建立虚拟源点&#xff0c;连接虚拟源点和 w w w个可作为起点的点&#xff0c;边权为0&#xff0c;这样只需要从虚拟源点开始做一遍最短路算法便可。 2.反向建边&#xff0c;把所有的add(a,b,c)变成add(b,a,c)&#xff0c;这样只…...

Linux shell脚本笔记-One

前言 本文主要汇总有关shell脚本常用的知识点&#xff0c;有时候使用忘记某些用法指令&#xff0c;特此汇总方便后续查阅。 一.shell脚本编写的头部定义: 定义的shell脚本头部有多种写法&#xff0c;具体根基实际系统结构处理&#xff0c;如下: #!/bin/sh &#xff…...

【C语言----函数详解】

目录 ----------------------------------------begin-------------------------------------- 引言 一、函数是什么 二、函数的定义和声明 1. 函数的定义 2. 函数的声明 三、函数的调用 四、函数参数传递 五、函数的返回值 六、递归函数 七、函数指针 八、总结 ---…...

QT交叉编译环境搭建(Cmake和qmake)

介绍一共有两种方法&#xff08;基于qmake和cmake&#xff09;&#xff1a; 1.直接调用虚拟机中的交叉编译工具编译 2.在QT中新建编译套件kits camke和qmake的区别&#xff1a;CMake 和 qmake 都是自动化构建工具&#xff0c;用于简化构建过程&#xff0c;管理编译设置&…...

Zemax 中的屋脊棱镜建模

光学棱镜是一种透明的光学元件&#xff0c;其表面平坦且抛光&#xff0c;可以折射光线。最常见的棱镜类型是三棱镜&#xff0c;它有两个三角形底座和三个矩形或略呈梯形的表面。棱镜通常由玻璃或丙烯酸等材料制成。当光线以一定角度进入棱镜时&#xff0c;它会在穿过棱镜时发生…...

CUDA学习-内存访问

一 访存合并 1.1 说明 本部分内容主要参考: 搞懂 CUDA Shared Memory 上的 bank conflicts 和向量化指令(LDS.128 / float4)的访存特点 - 知乎 1.2 share memory结构 图1.1 share memory结构 放在 shared memory 中的数据是以 4 bytes(即 32 bits)作为 1 个 word,依…...

Nginx 开发总结

文章目录 1. Nginx 基础概念1-1、什么是 Nginx1-2、Nginx 的工作原理1-3、Nginx 的核心特点1-4、Nginx 的常见应用场景1-5、Nginx 与 Apache 的区别1-6、 Nginx 配置的基本结构1-7、Nginx 常见指令 2. Nginx 配置基础2-1、Nginx 配置文件结构2-2、全局配置 (Global Block)2-3、…...

目标跟踪之sort算法(3)

这里写目录标题 1 流程1 预处理2 跟踪 2 代码 参考&#xff1a;sort代码 https://github.com/abewley/sort 1 流程 1 预处理 1.1 获取离线检测数据。1.2 实例化跟踪器。2 跟踪 2.1 轨迹处理。根据上一帧的轨迹预测当前帧的轨迹&#xff0c;剔除到当前轨迹中为空的轨迹得到当前…...

C++/stack_queue

目录 1.stack 1.1stack的介绍 1.2stack的使用 练习题&#xff1a; 1.3stack的模拟实现 2.queue的介绍和使用 2.1queue的介绍 2.2queue的使用 2.3queue的模拟实现 3.priority_queue的介绍和使用 3.1priority_queue的介绍 3.2priority_queue的使用 欢迎 1.stack 1.1stack…...

小程序电商运营内容真实性增强策略及开源链动2+1模式AI智能名片S2B2C商城系统源码的应用探索

摘要&#xff1a;随着互联网技术的不断发展&#xff0c;小程序电商已成为现代商业的重要组成部分。然而&#xff0c;如何在竞争激烈的市场中增强小程序内容的真实性&#xff0c;提高用户信任度&#xff0c;成为电商运营者面临的一大挑战。本文首先探讨了通过图片、视频等方式增…...

「Unity3D」在Unity中使用C#控制显示Android的状态栏

Unity打包的Android默认都是全屏&#xff0c;如果想要在真机上显示状态栏&#xff0c;就需要额外设置&#xff0c;有两种方式&#xff1a; 第一种&#xff0c;使用Android的Java代码去控制&#xff0c;然后以插件的方式放到Unity中&#xff0c;被C#调用。第二种&#xff0c;使…...

基于51单片机和ESP8266(01S)、LCD1602、DS1302、独立按键的WiFi时钟

目录 系列文章目录前言一、效果展示二、原理分析三、各模块代码1、延时2、定时器03、串口通信4、DS13025、LCD16026、独立按键 四、主函数总结 系列文章目录 前言 之前做了一个WiFi定时器时钟&#xff0c;用八位数码管进行显示&#xff0c;但是定时器时钟的精度较低&#xff0…...

AI 浪潮席卷中国年,开启科技新春新纪元

在这博主提前祝大家蛇年快乐呀&#xff01;&#xff01;&#xff01; 随着人工智能&#xff08;AI&#xff09;技术的飞速发展&#xff0c;其影响力已经渗透到社会生活的方方面面。在中国传统节日 —— 春节期间&#xff0c;AI 技术也展现出了巨大的潜力&#xff0c;为中国年带…...

STM32 LED呼吸灯

接线图&#xff1a; 这里将正极接到PA0引脚上&#xff0c;负极接到GND&#xff0c;这样就高电平点亮LED&#xff0c;低电平熄灭。 占空比越大&#xff0c;LED越亮&#xff0c;占空比越小&#xff0c;LED越暗 PWM初始化配置 输出比较函数介绍&#xff1a; 用这四个函数配置输…...

机器学习day4

自定义数据集 使用pytorch框架实现逻辑回归并保存模型&#xff0c;然后保存模型后再加载模型进行预测 import numpy as np import torch import torch.nn as nn import torch.optim as optimizer import matplotlib.pyplot as pltclass1_points np.array([[2.1, 1.8],[1.9, 2…...

《哈佛家训》

《哈佛家训》是一本以教育为主题的书籍&#xff0c;旨在通过一系列富有哲理的故事和案例&#xff0c;传递积极的人生观、价值观和教育理念。虽然它并非直接由哈佛大学官方出版&#xff0c;但其内容深受读者喜爱&#xff0c;尤其是在家庭教育和个人成长领域。 以下是《哈佛家训…...

为什么redis会开小差?Redis 频繁异常的深度剖析与解决方案

文章目录 导读为什么redis会开小差&#xff1f;1.连接数过多2.bigkey3.慢命令操作4.内存策略不合理5.外部数据双写一致性6.保护机制未开启7. 数据集中过期8. CPU饱和9. 持久化阻塞10. 网络问题结论 导读 提起分布式缓存&#xff0c;想必大多数同学脑海中都会浮出redis这个名字…...

window中80端口被占用问题

1&#xff0c;查看报错信息 可以看到在启动项目的时候&#xff0c;8081端口被占用了&#xff0c;导致项目无法启动。 2&#xff0c;查看被占用端口的pid #语法 netstat -aon|findstr :被占用端口#示例 netstat -aon|findstr :8080 3&#xff0c;杀死进程 #语法 taikkill /pid…...

< OS 有关 > 阿里云:轻量应用服务器 的使用 :轻量化 阿里云 vpm 主机

原因&#xff1a; &#xff1c; OS 有关 &#xff1e; 阿里云&#xff1a;轻量应用服务器 的使用 &#xff1a;从新开始 配置 SSH 主机名 DNS Tailscale 更新OS安装包 最主要是 清除阿里云客户端这个性能杀手-CSDN博客 防止 I/O 祸害系统 操作&#xff1a; 查看进程&#x…...

解决报错“The layer xxx has never been called and thus has no defined input shape”

解决报错“The layer xxx has never been called and thus has no defined input shape”(这里写自定义目录标题) 报错显示 最近在跑yolo的代码时遇到这样一个错误&#xff0c;显示“the layer {self.name} has never been called”.这个程序闲置了很久&#xff0c;每次一遇到…...

Microsoft Visual Studio 2022 主题修改(补充)

Microsoft Visual Studio 2022 透明背景修改这方面已经有很多佬介绍过了&#xff0c;今天闲来无事就补充几点细节。 具体的修改可以参考&#xff1a;Microsoft Visual Studio 2022 透明背景修改&#xff08;快捷方法&#xff09;_material studio怎么把背景弄成透明-CSDN博客文…...

PyCharm接入DeepSeek实现AI编程

目录 效果演示 创建API key 在PyCharm中下载CodeGPT插件 配置Continue DeepSeek 是一家专注于人工智能技术研发的公司&#xff0c;致力于开发高性能、低成本的 AI 模型。DeepSeek-V3 是 DeepSeek 公司推出的最新一代 AI 模型。其前身是 DeepSeek-V2.5&#xff0c;经过持续的…...