排序学习整理(1)

1.排序的概念及运用

1.1概念

排序:所谓排序,就是使⼀串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作,以便更容易查找、组织或分析数据。

1.2运用

 购物筛选排序

院校排名

1.3常见排序算法

2.实现常见排序算法

int a[] = {5, 3, 9, 6, 2, 4, 7, 1, 8};

2.1 插入排序

把待排序的记录按其关键码值的大小逐个插入到⼀个已经排好序的有序序列中,直到所有的记录插入完为止,得到⼀个新的有序序列 。

2.1.1 直接插入排序

直接插入排序(Direct Insertion Sort)是一种简单直观的排序算法,它通过逐步构建有序序列,将未排序部分的元素插入到已排序部分的适当位置,直到整个数组排序完成。

基本思想

1.将数组分为 已排序部分 和 未排序部分。

                初始时,已排序部分只有第一个元素。

                未排序部分为剩余的元素。

2.依次从未排序部分取出一个元素,插入到已排序部分的正确位置。

3.重复以上操作,直到未排序部分为空。

算法步骤

1.从数组的第二个元素(索引为 1)开始,依次向后遍历。

                对当前元素,在已排序部分从后向前查找其插入位置:

                如果已排序部分的元素大于当前元素,则将其向后移动。

2.找到插入位置后,将当前元素放入。

3.重复此过程,直到所有元素排序完成。

当插入第 i(i>=1) 个元素时,前⾯的 array[0],array[1],…,array[i-1] 已经排好序,此时用 array[i] 的排序码与 array[i-1],array[i-2],… 的排序码顺序进行比较,找到插入位置即将 array[i] 插入,原来位置上的元素顺序后移
代码实现
void InsertSort(int* a, int n) {for (int i = 1; i < n; i++) {// 当前要插入的元素int tmp = a[i];// 已排序部分的最后一个元素的索引int j = i - 1;// 从后向前查找插入位置while (j >= 0 && a[j] > tmp) {a[j + 1] = a[j]; // 后移元素j--;}// 将当前元素插入到正确的位置a[j + 1] = tmp;}
}
特性总结
算法复杂度
  1. 时间复杂度
    • 最坏情况(数组逆序):O(n^2)
    • 最好情况(数组已排序):O(n)
    • 平均情况:O(n^2)
  2. 空间复杂度:原地排序,不需要额外的辅助空间,空间复杂度为 O(1)
  3. 稳定性:直接插入排序是稳定的,因为在插入过程中不会改变相等元素的相对顺序。

优缺点

优点

  1. 简单直观:实现容易,适合小规模数据。
  2. 性能良好:当数组接近有序时,插入排序的效率很高,接近 O(n)

缺点:

  1. 效率低下:对大规模、随机分布的数组排序效率较低,时间复杂度较高。
  2. 大量数据移动:当数组逆序时,几乎每次插入都需要移动大量元素。

适用场景
  1. 数据量较小(如 n <= 100)时,插入排序是一种简单有效的选择。
  2. 数据本身接近有序时(如几乎按升序排列),插入排序效率很高。

2.1.2 希尔排序 

希尔排序又称缩小增量法是一种基于插入排序的改进算法,得名于其发明者 Donald Shell。它通过分组和逐步缩小分组间距(增量),使得数据能够更快地接近有序,从而提高排序效率。

基本思想

先选定⼀个整数(通常是gap = n/3 + 1),把待排序文件所有记录分成各组,所有的距离相等的记录分在同⼀组内,并对每⼀组内的记录进⾏排序,然后gap = gap/3 + 1得到下⼀个整数,再将数组分成各组,进入插入排序,当gap = 1时,就相当于直接插入排序。

它是在直接插入排序算法的基础上进行改进而来的,综合来说它的效率肯定是要高于直接插入排序算法的。

算法步骤
  1. 初始化 gap = n / 3 + 1,其中 n 是数组的长度。
  2. 按照当前的 gap 将数组分组,对每组进行插入排序。
  3. 缩小 gap,继续分组排序,直到 gap = 1
  4. gap = 1 时,进行最后一次插入排序,数组有序。

 

代码实现
void ShellSort(int* a, int n) {int gap = n;// 缩小增量,直到 gap == 1while (gap > 1) {gap = gap / 3 + 1;// 分组for (int group = 0; group < gap; group++) { // 控制每组// 每组独立进行插入排序for (int i = group + gap; i < n; i += gap) {int tmp = a[i];int j = i - gap;while (j >= group && a[j] > tmp) {a[j + gap] = a[j];j -= gap;}a[j + gap] = tmp;}}}
}

显式地将数组分组,每组独立排序后再继续调整增量 gap,这种更好理解分组排序的原理,但代码稍显冗长,所以我一般用这种

void ShellSort1(int* a, int n) {int gap = n;// 缩小增量,直到 gap == 1while (gap > 1) {gap = gap / 3 + 1;// 从 gap 开始,模拟插入排序for (int i = gap; i < n; i++) {int tmp = a[i]; // 当前待插入的元素int j = i - gap;// 插入排序逻辑,按 gap 步长比较和移动while (j >= 0 && a[j] > tmp) { // 在同组中向前查找a[j + gap] = a[j]; // 将较大的元素后移j -= gap; // 按 gap 步长继续比较}a[j + gap] = tmp; // 插入到合适位置}}
}

这种方法也叫“简单希尔排序”(Simple Shell Sort),或者直接叫并着走,它直接在外层控制增量 gap,然后在整个数组中按步长进行插入排序,逻辑比较直观,效率高。这种实现方法更贴近希尔排序的本质,适合直接应用于实际场景。

它的核心思想是

  • 希尔排序的分组本质上是用 步长 gap 控制哪些元素属于一个组。

    • 在并着走的实现中,假设 gap = 3
      • 对于索引为 0, 3, 6, 9... 的元素,它们属于第一组。
      • 对于索引为 1, 4, 7, 10... 的元素,它们属于第二组。
      • 对于索引为 2, 5, 8, 11... 的元素,它们属于第三组。
    • 并着走的逻辑是遍历整个数组,隐式地让这些组在同一个循环中排序。
  • gap 的控制下:

    • 每个位置 i 的元素 a[i],都会和同组的前一个元素(位置 i - gap)进行比较。
    • 如果需要交换位置,就不断向前检查,直到找到合适位置。
特性总结
算法复杂度

1.时间复杂度

                最坏情况:O(n^2)(不理想的增量序列)。

                平均情况:O(n^(3/2)) 或更优(根据增量序列)。

                最好情况:接近 O(n)

可以分成内外层来分析

外层循环(控制增量 gap):应该能直接看出来吧,无疑问的O(log(n)),就是增量序列的长度。

内层循环(分组插入排序):

假设⼀共有n个数据,合计gap组,则每组为n / gap个;在每组中,插入移动的次数最坏的情况下为 1 + 2 + 3 + .... + ( n / gap− 1)),⼀共是gap组,因此: 1 + 2 + 3 + .... + ( n / gap− 1))
总计最坏情况下移动总数为: gap ∗ (1 + 2 + 3 + .... + (n / gap − 1 ))
gap取值有(以除3为例):n / 3  n / 9  n / 27 ......  2  1
  • 当gap为n / 3时,移动总数为: n / 3 * (1 + 2) = n
  • 当gap为n / 9时,移动总数为: n / 9 * (1 + 2 + 3 + .... + 8) = (n / 9) * (8 (1 + 8) / 2)= 4n
  • 最后⼀趟,gap=1,即直接插入排序,内层循环排序消耗为n

可知,比较次数是先增加再下降的,或者画一张曲线图更好理解

因此,希尔排序在最初和最后的排序的次数都为n,即前⼀阶段排序次数是逐渐上升的状态,当到达某⼀顶点时,排序次数逐渐下降至n,而该顶点的计算暂时无法给出具体的计算过程
所以,目前其实没有明确的希尔排序的时间复杂度,普遍认为的话是在 O(n^1.3) ,这里我们引用充当教科书较多的 《数据结构(C语言版)》--- 严蔚敏书中给出的时间复杂度的解释

 

2.空间复杂度:使用原地排序,额外空间复杂度为 O(1)

3.稳定性不稳定,因为在分组时可能会打乱相同元素的相对顺序。


优缺点

优点

  1. 简单易实现。
  2. 对中等规模的数组(如 1 万以下)性能较好。
  3. 在基本有序的数组上效率较高。

缺点

  1. 不稳定,不能保证相同元素的顺序。
  2. 对非常大的数组,效率不如快速排序。

增量序列的选择
  • 希尔增量gap = gap / 3 + 1
  • Hibbard增量gap = 2^k - 1
  • Sedgewick增量gap = 9 * 4^i - 9 * 2^i + 1 等。
  • 增量序列的选择会显著影响希尔排序的性能。

适用场景
  1. 数据规模适中(几百到几万)。
  2. 数据分布无规律,但需要排序效率较高的场景。
  3. 对性能要求高,但稳定性不重要的场景。

2.2 选择排序 

每⼀次从待排序的数据元素中选出最小或最大的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完 。

2.2.1 直接选择排序 

直接选择排序(Selection Sort)是一种简单的排序算法,其基本思想是每次从待排序的序列中选择最小(或最大)元素,将其放到已排序序列的末尾。该算法属于交换排序类,通过多次选择最小(或最大)元素并与当前序列中的元素交换来逐步完成排序。

基本思想
  1. 选择最小元素:在每一轮中,找到剩余未排序部分的最小元素。
  2. 交换位置:将找到的最小元素与当前已排序部分的末尾元素交换位置。
  3. 重复:每次排好一个元素后,缩小待排序部分的范围,继续执行选择和交换操作,直到所有元素排序完成。
算法步骤 
  1. 假设数组长度为 n,开始时将整个数组看作未排序部分。
  2. 从第一个元素开始,扫描剩余部分,找到最小的元素。
  3. 将最小元素与当前待排序部分的第一个元素交换。
  4. 重复此过程,直到排序完成。
1. 在元素集合 array[i]--array[n-1] 中选择关键码最大(小)的数据元素
2. 若它不是这组元素中的最后一个(第一个)元素,则将它与这组元素中的最后一个(第一个)元素
交换
3. 在剩余的 array[i]--array[n-2](array[i+1]--array[n-1]) 集合中,重复上述步骤,直到集合剩余 1 个元素
代码实现
void SelectionSort(int* a, int n) {// 外层循环控制已排序部分的末尾for (int i = 0; i < n - 1; i++) {int minIndex = i;// 内层循环在未排序部分中寻找最小值for (int j = i + 1; j < n; j++) {if (a[j] < a[minIndex]) {minIndex = j;  // 记录最小元素的索引}}// 交换最小元素与当前已排序部分的下一个元素if (minIndex != i) {int temp = a[i];a[i] = a[minIndex];a[minIndex] = temp;}}
}
特性总结
算法复杂度

1.时间复杂度

                最坏情况(数组逆序):O(n^2)

                最好情况(数组已排序):O(n^2)(即数组已经排序,选择排序仍需执行完整的循环)

                平均情况O(n^2)

2.空间复杂度原地排序:不需要额外的辅助空间,空间复杂度为 O(1)

3.稳定性不稳定:在排序过程中可能会改变相等元素的相对顺序,因为会交换位置。


优缺点

优点

  1. 简单直观:直接选择排序算法的实现简单,易于理解,适合小规模数据。
  2. 空间效率高:只使用常数级的额外空间,内存开销小。

缺点

  1. 效率低下:由于时间复杂度为 O(n^2),对于大规模数据,性能较差。
  2. 不稳定:相同元素的顺序可能被改变,导致排序不稳定。
  3. 交换次数较多:每次找到最小元素后都会交换,可能导致不必要的交换操作。

适用场景
  1. 数据量较小(如 n <= 100)时,选择排序是一种简单有效的排序方法,适合小规模数据的排序。
  2. 数据本身接近有序时,直接选择排序的性能相对较好,尽管时间复杂度为 O(n^2),但相较于其他 O(n^2) 算法,选择排序的交换次数较少。

2.2.2 堆排序

堆排序(Heap Sort)是一种基于堆数据结构的排序算法,堆是一种完全二叉树,满足堆的性质:

  • 最大堆(Max Heap):父节点的值大于或等于其子节点的值,根节点是最大元素。
  • 最小堆(Min Heap):父节点的值小于或等于其子节点的值,根节点是最小元素。

堆排序利用堆的性质,每次从堆中提取根节点(最大或最小),然后调整堆结构,从而实现排序。

基本思想 
  1. 构建堆:将待排序数组转换成一个堆结构(可以是最大堆或最小堆),通常构建最大堆。
  2. 交换根节点与最后一个节点:将堆顶(最大元素)与堆的最后一个元素交换,这样最大元素就被放置到了正确的位置。
  3. 调整堆:交换后,堆的结构可能被破坏,需要重新调整堆,使其恢复堆的性质。
  4. 重复:将剩下的部分继续调整为堆,再次进行交换,直到所有元素都排序完成。
算法步骤
  1. 建堆:将给定的数组转换成一个最大堆。
  2. 交换根节点和最后一个节点:把堆顶元素(最大值)交换到数组的末尾。
  3. 调整堆:将剩余部分重新调整为最大堆。
  4. 重复交换和调整过程,直到堆的大小减小为1。
代码实现 
#include <stdio.h>// 调整堆结构
void AdjustDown(int* a, int n, int parent) {int child = parent * 2 + 1;  // 左子节点的索引while (child < n) {// 如果有右子节点,且右子节点更大,则选择右子节点if (child + 1 < n && a[child + 1] > a[child]) {child++;}// 如果父节点小于最大子节点,则交换if (a[child] > a[parent]) {int temp = a[parent];a[parent] = a[child];a[child] = temp;parent = child;child = parent * 2 + 1;  // 继续向下调整} else {break;  // 如果父节点大于等于最大子节点,则结束}}
}// 堆排序主函数
void HeapSort(int* a, int n) {// 建堆(从最后一个非叶子节点开始调整堆)for (int i = (n - 1) / 2; i >= 0; --i) {AdjustDown(a, n, i);}// 交换根节点(最大元素)和最后一个元素,然后调整堆int end = n - 1;while (end > 0) {// 交换根节点与堆的最后一个元素int temp = a[0];a[0] = a[end];a[end] = temp;// 重新调整堆AdjustDown(a, end, 0);--end;}
}// 打印数组
void PrintArray(int* a, int n) {for (int i = 0; i < n; ++i) {printf("%d ", a[i]);}printf("\n");
}int main() {int arr[] = {4, 10, 3, 5, 1};int n = sizeof(arr) / sizeof(arr[0]);HeapSort(arr, n);PrintArray(arr, n);return 0;
}
堆排序的步骤演示

假设我们有一个数组 [4, 10, 3, 5, 1],我们来逐步演示堆排序的过程。

1.建堆:首先将数组转换为最大堆:

      AdjustDown 会从最后一个非叶子节点开始,调整堆结构。

                经过调整,最大堆应该是 [10, 5, 3, 4, 1]

2.交换根节点和最后一个元素:交换根节点 10 和数组末尾的元素 1,得到 [1, 5, 3, 4, 10]

                通过 AdjustDown 调整堆,使其重新恢复堆的性质,得到 [5, 4, 3, 1, 10]

3.再次交换根节点和最后一个元素:交换根节点 5 和倒数第二个元素 1,得到 [1, 4, 3, 5, 10]

                通过 AdjustDown 调整堆,得到 [4, 1, 3, 5, 10]

4.重复:继续交换并调整堆,直到整个数组排好序:

                交换后得到 [3, 1, 4, 5, 10]

                调整后得到 [3, 1, 4, 5, 10]

                最终得到排序结果 [1, 3, 4, 5, 10]

特性总结
算法复杂度

1.时间复杂度

                最坏情况(数组逆序):O(n log n)

                最好情况(数组已排序):O(n log n)

                平均情况O(n log n)

2.空间复杂度原地排序:堆排序不需要额外的辅助空间,空间复杂度为 O(1)

3.稳定性不稳定:堆排序在排序过程中可能改变相等元素的相对顺序,因此是一个不稳定的排序算法。


优缺点

优点

  1. 时间复杂度稳定:无论在最坏、最好还是平均情况下,堆排序的时间复杂度始终为 O(n log n),表现稳定。
  2. 原地排序:堆排序只使用常数级额外空间,空间复杂度为 O(1),内存开销小。
  3. 适用于大规模数据:由于堆排序的时间复杂度较为稳定,因此适合用于处理大规模数据的排序任务。

缺点

  1. 不稳定:堆排序不保持相等元素的相对顺序,因此不适用于需要稳定排序的场景。
  2. 常数因子较大:虽然时间复杂度为 O(n log n),但堆排序的常数因子较大,通常会比其他如快速排序的实际性能稍差。

适用场景
  1. 大规模数据的排序:堆排序在处理大数据时较为稳定,尤其是在对时间复杂度有较高要求时。
  2. 内存有限的情况:堆排序是原地排序,不需要额外的内存,适用于内存受限的情况。
  3. 需要稳定时间复杂度的场景:当不关心排序的稳定性时,堆排序是一个不错的选择,尤其是在无法预测输入数据分布的情况下。

下一章应该是介绍冒泡和快速排序(

那几种快速排序够写很多了(

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

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

相关文章

【Rust】unsafe rust入门

这篇文章简单介绍下unsafe rust的几个要点 1. 解引用裸指针 裸指针其实就是C或者说C的指针&#xff0c;与C的指针不同的是&#xff0c;Rust的裸指针还是要分为可变和不可变&#xff0c;*const T 和 *mut T&#xff1a; 基于引用创建裸指针 let mut num 5;let r1 &num …

# 01_Python基础到实战一飞冲天(三)--python面向对象(一)--简单类

01_Python基础到实战一飞冲天&#xff08;三&#xff09;–python面向对象&#xff08;一&#xff09;–简单类 一、面向对象-01-基本概念 1、面向对象(OOP) 面向对象编程 —— Object Oriented Programming 简写 OOP。 2、面向对象(OOP) 学习目标 了解 面向对象 基本概念…

Java 基础知识与核心概念

Java 作为一门广泛使用的编程语言&#xff0c;它的基础知识是每个开发者必须掌握的。无论是面向对象编程&#xff08;OOP&#xff09;还是集合框架的使用&#xff0c;理解这些核心概念能够帮助我们在日常开发中更加高效和准确地编写代码。本文将从设计模式、集合原理到常见类的…

【C++习题】24.二分查找算法_0~n-1中缺失的数字

文章目录 题目链接&#xff1a;题目描述&#xff1a;解法C 算法代码&#xff1a;图解 题目链接&#xff1a; 剑指 Offer 53 - II. 0&#xff5e;n-1中缺失的数字 题目描述&#xff1a; 解法 哈希表&#xff1a; 建立一个hash表看哪个数字出现次数为0 直接遍历找结果&#xff1…

(即插即用模块-Convolution部分) 一、(ICLR 2022) ODConv 全维动态卷积

文章目录 1、Omni-dimensional Dynamic Convolution2、代码实现 paper&#xff1a;OMNI-DIMENSIONAL DYNAMIC CONVOLUTION Code&#xff1a;https://github.com/OSVAI/ODConv 1、Omni-dimensional Dynamic Convolution 论文首先分析了现有动态卷积的局限性&#xff0c;论文指出…

深度学习Python基础(2)

二 数据处理 一般来说PyTorch中深度学习训练的流程是这样的&#xff1a; 1. 创建Dateset 2. Dataset传递给DataLoader 3. DataLoader迭代产生训练数据提供给模型 对应的一般都会有这三部分代码 # 创建Dateset(可以自定义) dataset face_dataset # Dataset部分自定义过的…

(超详细图文详情)Navicat 配置连接 Oracle

1、下载依赖文件 Oracle官网下载直链&#xff1a;https://www.oracle.com/database/technologies/instant-client/winx64-64-downloads.html 夸克网盘下载&#xff08;oracle19c版本&#xff09;&#xff1a;https://pan.quark.cn/s/5061e690debc 官网下载选择对应 Oracle 版…

jdk各个版本介绍

Java Development Kit&#xff08;JDK&#xff09;是Java平台的核心组件&#xff0c;它包含了Java编程语言、Java虚拟机&#xff08;JVM&#xff09;、Java类库以及用于编译、调试和运行Java应用程序的工具。 JDK 1.0-1.4&#xff08;经典时代&#xff09; • JDK 1.0&#xff…

二分法篇——于上下边界的扭转压缩间,窥见正解辉映之光(1)

前言 二分法&#xff0c;这一看似简单却又充满哲理的算法&#xff0c;犹如一道精巧的数学之门&#xff0c;带领我们在问题的迷雾中找到清晰的道路。它的名字虽简单&#xff0c;却深藏着智慧的光辉。在科学的浩瀚星空中&#xff0c;二分法如一颗璀璨的星辰&#xff0c;指引着我们…

基于 FFmpeg/Scrcpy 框架构建的一款高性能的安卓设备投屏管理工具-供大家学习研究参考

支持的投屏方式有:USB,WIFIADB,OTG,投屏之前需要开启开发者选项里面的USB调试。 主要功能有: 1.支持单个或多个设备投屏。 2.支持键鼠操控。 3.支持文字输入。 4.支持共享剪切板(可复制粘贴电脑端文字到手机端,也可导出手机剪切板到电脑端)。 5.支持视频图片上传,可单…

【论文笔记】A Token-level Contrastive Framework for Sign Language Translation

&#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&#xff0c;为生民立命&#xff0c;为往圣继绝学&#xff0c;为万世开太平。 基本信息 标题: A Token-level Contrastiv…

ROS2教程 - 3 HelloWorld

更好的阅读体验&#xff1a;https://www.foooor.com 3 HelloWorld 下面从 HelloWorld 开始&#xff0c;讲解 ROS2 的开发。 ROS 开发主要使用 C 或 Python 实现&#xff0c;如果要实现的功能&#xff0c;对性能有要求&#xff0c;可以使用 C 实现&#xff0c;如果对性能没有…

洛谷 B3626 跳跃机器人 C语言 记忆化搜索

题目&#xff1a; https://www.luogu.com.cn/problem/B3626 题目描述 地上有一排格子&#xff0c;共 n 个位置。机器猫站在第一个格子上&#xff0c;需要取第 n 个格子里的东西。 机器猫当然不愿意自己跑过去&#xff0c;所以机器猫从口袋里掏出了一个机器人&#xff01;这…

【AI】Sklearn

长期更新&#xff0c;建议关注、收藏、点赞。 友情链接&#xff1a; AI中的数学_线代微积分概率论最优化 Python numpy_pandas_matplotlib_spicy 建议路线&#xff1a;机器学习->深度学习->强化学习 目录 预处理模型选择分类实例&#xff1a; 二分类比赛 网格搜索实例&…

⭐️ GitHub Star 数量前十的工作流项目

文章开始前&#xff0c;我们先做个小调查&#xff1a;在日常工作中&#xff0c;你会使用自动化工作流工具吗&#xff1f;&#x1f64b; 事实上&#xff0c;工作流工具已经变成了提升效率的关键。其实在此之前我们已经写过一篇博客&#xff0c;跟大家分享五个好用的工作流工具。…

Tree搜索二叉树、map和set_数据结构

数据结构专栏 如烟花般绚烂却又稍纵即逝的个人主页 本章讲述数据结构中搜索二叉树与HashMap的学习&#xff0c;感谢大家的支持&#xff01;欢迎大家踊跃评论&#xff0c;感谢大佬们的支持! 目录 搜索二叉树的概念二叉树搜索模拟实现搜索二叉树查找搜索二叉树插入搜索二叉树删除…

Swift实现高效链表排序:一步步解读

文章目录 前言摘要问题描述题解解题思路Swift 实现代码代码分析示例测试与结果 时间复杂度空间复杂度总结关于我们 前言 本题由于没有合适答案为以往遗留问题&#xff0c;最近有时间将以往遗留问题一一完善。 148. 排序链表 不积跬步&#xff0c;无以至千里&#xff1b;不积小流…

【开篇】.NET开源 ORM 框架 SqlSugar 系列

.NET开源 ORM 框架 SqlSugar 系列 【开篇】.NET开源 ORM 框架 SqlSugar 系列【入门必看】.NET开源 ORM 框架 SqlSugar 系列【实体配置】.NET开源 ORM 框架 SqlSugar 系列【Db First】.NET开源 ORM 框架 SqlSugar 系列【Code First】.NET开源 ORM 框架 SqlSugar 系列【数据事务…

qt QAnimationDriver详解

1、概述 QAnimationDriver是Qt框架中提供的一个类&#xff0c;它主要用于自定义动画帧的时间控制和更新。通过继承和实现QAnimationDriver&#xff0c;开发者可以精确控制动画的时间步长和更新逻辑&#xff0c;从而实现丰富和灵活的动画效果。QAnimationDriver与QAbstractAnim…

何时在 SQL 中使用 CHAR、VARCHAR 和 VARCHAR(MAX)

在管理数据库表时&#xff0c;考虑 CHAR、VARCHAR 和 VARCHAR(MAX) 是必不可少的。此外&#xff0c;使用正确的工具&#xff08;例如dbForge Studio for SQL Server&#xff09; &#xff0c;与数据库相关的任务都会变得更加容易。它是针对 SQL Server 专业人员的强大的一体化解…