软考 - 排序算法

排序算法是软件设计师考试数据结构与算法 部分的核心内容,每年必考。下面我将按照考试大纲要求,对所有排序算法进行系统讲解。

一、排序算法概览与分类

1.1 按算法思想分类

类别 算法 时间复杂度(平均) 空间复杂度 稳定性
插入类 直接插入排序 O(n²) O(1) 稳定
希尔排序 O(n^1.3) O(1) 不稳定
交换类 冒泡排序 O(n²) O(1) 稳定
快速排序 O(n log n) O(log n) 不稳定
选择类 简单选择排序 O(n²) O(1) 不稳定
堆排序 O(n log n) O(1) 不稳定
归并类 归并排序 O(n log n) O(n) 稳定
基数类 基数排序 O(d(n+r)) O(n+r) 稳定

1.2 必须掌握的核心考点

  1. 算法思想:手写伪代码或填空
  2. 时间复杂度分析:最好、最坏、平均
  3. 稳定性判断:相等元素相对位置是否改变
  4. 适用场景:数据规模、初始状态
  5. 优化方法:针对特定情况的改进

二、插入类排序(逐个插入有序序列)

2.1 直接插入排序

算法思想

将待排序序列分为已排序未排序两部分,每次从未排序部分取出第一个元素,在已排序部分找到合适位置插入。

执行过程示例
复制代码
初始: [49, 38, 65, 97, 76, 13, 27]
第1轮:38插入[49] → [38, 49, 65, 97, 76, 13, 27]
第2轮:65插入[38,49] → [38, 49, 65, 97, 76, 13, 27]
第3轮:97插入[38,49,65] → [38, 49, 65, 97, 76, 13, 27]
第4轮:76插入[38,49,65,97] → [38, 49, 65, 76, 97, 13, 27]
第5轮:13插入[38,49,65,76,97] → [13, 38, 49, 65, 76, 97, 27]
第6轮:27插入[13,38,49,65,76,97] → [13, 27, 38, 49, 65, 76, 97]
代码实现(C语言)
c 复制代码
void InsertSort(int arr[], int n) {
    int i, j, temp;
    for (i = 1; i < n; i++) {  // 默认arr[0]已排序
        temp = arr[i];          // 待插入元素
        j = i - 1;
        while (j >= 0 && arr[j] > temp) {  // 找插入位置
            arr[j + 1] = arr[j];           // 元素后移
            j--;
        }
        arr[j + 1] = temp;      // 插入
    }
}
复杂度分析
  • 最好情况(已有序):O(n),只比较n-1次,不移动
  • 最坏情况(逆序):O(n²),比较+移动约n²/2次
  • 平均情况:O(n²)
  • 空间复杂度:O(1),只需一个临时变量
考点解析
  1. 稳定性:稳定。因为碰到相等元素时,插入位置在相等元素后面
  2. 适用场景
    • 数据量小(n < 1000)
    • 数据基本有序(效率接近O(n))
    • 要求稳定性
  3. 考试常见题
    • 给定序列,写出每轮排序结果
    • 计算比较次数和移动次数
    • 与选择排序比较(插入排序对有序数据效率极高)

2.2 希尔排序(缩小增量排序)

算法思想

是直接插入排序的改进版。通过分组 插入排序,让元素快速移动到大致正确的位置,最后整体进行一次插入排序。核心是增量序列的选取。

执行过程示例(增量序列:5, 3, 1)
复制代码
初始: [49, 38, 65, 97, 76, 13, 27, 49, 55, 04]

第一趟(dk=5):分成5组
组1: [49, 13] → [13, 49]
组2: [38, 27] → [27, 38]
组3: [65, 49] → [49, 65]
组4: [97, 55] → [55, 97]
组5: [76, 04] → [04, 76]
结果:[13, 27, 49, 55, 04, 49, 38, 65, 97, 76]

第二趟(dk=3):分成3组
组1: [13, 55, 38, 76] → 插入排序 → [13, 38, 55, 76]
组2: [27, 04, 65] → [04, 27, 65]
组3: [49, 49, 97] → [49, 49, 97]
结果:[13, 04, 49, 38, 27, 49, 55, 65, 97, 76]

第三趟(dk=1):直接插入排序
结果:[04, 13, 27, 38, 49, 49, 55, 65, 76, 97]
代码实现
c 复制代码
void ShellSort(int arr[], int n) {
    int i, j, temp, dk;
    // 增量序列:n/2, n/4, ..., 1
    for (dk = n/2; dk >= 1; dk = dk/2) {
        for (i = dk; i < n; i++) {  // 从每个组的第二个元素开始
            temp = arr[i];
            j = i - dk;
            while (j >= 0 && arr[j] > temp) {
                arr[j + dk] = arr[j];
                j -= dk;
            }
            arr[j + dk] = temp;
        }
    }
}
复杂度分析
  • 时间复杂度 :与增量序列选择有关
    • Shell原始增量(n/2, n/4, ..., 1):O(n²)
    • Hibbard增量(1, 3, 7, ..., 2k-1):O(n(3/2))
    • Sedgewick增量:O(n^(4/3))
  • 空间复杂度:O(1)
  • 稳定性不稳定(分组插入可能导致相等元素交换顺序)
考点解析
  1. 核心思想:利用插入排序在数据基本有序时效率高的特点
  2. 增量序列特点
    • 最后一个增量必须为1
    • 增量不宜互为倍数(最好互质)
  3. 考试重点
    • 给定初始序列和增量序列,写出每趟结果
    • 判断稳定性(易错点:希尔排序不稳定)
    • 与直接插入排序比较(希尔排序更快,但不稳定)

三、交换类排序(两两比较交换)

3.1 冒泡排序

算法思想

重复遍历序列,每次比较相邻两个元素,顺序错误就交换。每趟遍历会将当前未排序部分的最大(或最小)元素"浮"到最后。

执行过程示例
复制代码
初始:  [49, 38, 65, 97, 76, 13, 27]
第1趟:38,49,65,76,13,27,[97]  ← 97归位
比较:49-38交换 38-65不换 65-97不换 97-76交换 97-13交换 97-27交换
第2趟:38,49,65,13,27,[76,97]  ← 76归位
第3趟:38,49,13,27,[65,76,97]
第4趟:38,13,27,[49,65,76,97]
第5趟:13,27,[38,49,65,76,97]
第6趟:13,[27,38,49,65,76,97]
优化版代码
c 复制代码
void BubbleSort(int arr[], int n) {
    int i, j, temp;
    int swapped;  // 优化标志
    for (i = 0; i < n-1; i++) {
        swapped = 0;
        for (j = 0; j < n-1-i; j++) {
            if (arr[j] > arr[j+1]) {
                temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
                swapped = 1;
            }
        }
        if (swapped == 0) break;  // 没有交换,已有序
    }
}
复杂度分析
  • 最好情况(已有序):O(n),优化后只需一趟
  • 最坏情况(逆序):O(n²)
  • 平均情况:O(n²)
  • 空间复杂度:O(1)
  • 稳定性稳定(相等元素不交换)
考点解析
  1. 优化技巧
    • 设置swapped标志,提前结束
    • 记录最后一次交换位置,减少比较次数
  2. 适用场景:数据量小,或基本有序(教学常用)
  3. 考试形式
    • 手工模拟排序过程
    • 计算比较次数和交换次数
    • 对比其他简单排序

3.2 快速排序 ⭐⭐⭐(重中之重)

算法思想

分治法 的典型应用。选择一个基准元素(pivot),通过一趟排序将序列分为两部分:左边都≤pivot,右边都≥pivot。然后递归地对左右两部分进行同样操作。

核心操作:Partition(划分)
c 复制代码
int Partition(int arr[], int low, int high) {
    int pivot = arr[low];  // 选择第一个元素为基准
    int i = low, j = high;
    
    while (i < j) {
        // 从右向左找第一个小于pivot的元素
        while (i < j && arr[j] >= pivot) j--;
        if (i < j) arr[i++] = arr[j];
        
        // 从左向右找第一个大于pivot的元素
        while (i < j && arr[i] <= pivot) i++;
        if (i < j) arr[j--] = arr[i];
    }
    arr[i] = pivot;  // 基准归位
    return i;        // 返回基准位置
}
完整代码
c 复制代码
void QuickSort(int arr[], int low, int high) {
    if (low < high) {
        int pivotPos = Partition(arr, low, high);
        QuickSort(arr, low, pivotPos - 1);   // 左半部分递归
        QuickSort(arr, pivotPos + 1, high);  // 右半部分递归
    }
}
执行过程示例
复制代码
初始: [49, 38, 65, 97, 76, 13, 27]
选择49为基准:
第一次划分:左[27,38,13] 49 右[76,97,65]
递归左:[27,38,13] 选27为基准 → [13] 27 [38] → 归位
递归右:[76,97,65] 选76为基准 → [65] 76 [97] → 归位
最终:[13,27,38,49,65,76,97]
复杂度分析
  • 最好情况:每次划分都均匀,T(n)=2T(n/2)+O(n) → O(n log n)
  • 最坏情况:序列已有序或逆序,每次划分极不均匀 → O(n²)
  • 平均情况:O(n log n)(数学期望)
  • 空间复杂度:O(log n)(递归栈深度)
  • 稳定性不稳定(交换时可能改变相等元素顺序)
优化方法(考试常见)
  1. 基准选择优化
    • 随机选择基准
    • 三数取中(左、中、右三个位置的中位数)
  2. 小数组优化:当子数组长度小于阈值(如10),改用插入排序
  3. 尾递归优化:减少递归深度
考点解析(高频)
  1. 算法思想:分治 + 划分
  2. 手工模拟:给定序列,写出每趟划分结果
  3. 时间复杂度分析:理解最好、最坏、平均情况
  4. 空间复杂度:递归栈空间(易错点)
  5. 与归并排序比较
    • 快排不均匀时可能退化为O(n²),归并始终O(n log n)
    • 快排空间O(log n)更好,归并需要O(n)额外空间
    • 快排不稳定,归并稳定
    • 快排实际运行速度通常更快(常数小)

四、选择类排序(选最小/最大)

4.1 简单选择排序

算法思想

每趟在未排序部分选择最小(或最大)元素,放到已排序部分的末尾。

代码实现
c 复制代码
void SelectSort(int arr[], int n) {
    int i, j, minIdx, temp;
    for (i = 0; i < n-1; i++) {
        minIdx = i;
        for (j = i+1; j < n; j++) {
            if (arr[j] < arr[minIdx]) {
                minIdx = j;
            }
        }
        if (minIdx != i) {
            temp = arr[i];
            arr[i] = arr[minIdx];
            arr[minIdx] = temp;
        }
    }
}
执行过程示例
复制代码
初始: [49, 38, 65, 97, 76, 13, 27]
第1趟:找最小值13,与49交换 → [13, 38, 65, 97, 76, 49, 27]
第2趟:找次小值27,与38交换 → [13, 27, 65, 97, 76, 49, 38]
第3趟:找38,与65交换 → [13, 27, 38, 97, 76, 49, 65]
第4趟:找49,与97交换 → [13, 27, 38, 49, 76, 97, 65]
第5趟:找65,与76交换 → [13, 27, 38, 49, 65, 97, 76]
第6趟:找76,与97交换 → [13, 27, 38, 49, 65, 76, 97]
复杂度分析
  • 时间复杂度:始终 O(n²),比较次数固定为 n(n-1)/2
  • 空间复杂度:O(1)
  • 稳定性不稳定(示例中的38和65交换破坏了稳定性)
考点解析
  1. 与冒泡排序比较
    • 选择排序交换次数少(最多n-1次),但比较次数固定
    • 冒泡排序可提前结束,选择排序不能
    • 选择排序不稳定,冒泡稳定
  2. 特点:实现简单,不依赖初始状态,适合n较小且交换代价高的场景
  3. 考试易错:误以为选择排序稳定(实际不稳定)

4.2 堆排序 ⭐⭐⭐(数据结构重点)

算法思想

利用这种完全二叉树结构进行排序。先构建大顶堆(父节点≥子节点),然后每次将堆顶(最大值)与最后一个元素交换,再调整剩余元素为堆。

核心操作:调整堆(建堆/下沉)
c 复制代码
// 将以k为根的子树调整为堆,heapSize为当前堆大小
void HeapAdjust(int arr[], int k, int heapSize) {
    int temp = arr[k];
    int child = 2 * k;  // 左孩子
    
    while (child <= heapSize) {
        // 选出较大的孩子
        if (child < heapSize && arr[child+1] > arr[child]) {
            child++;
        }
        // 如果父节点≥较大孩子,调整结束
        if (temp >= arr[child]) break;
        
        arr[child/2] = arr[child];  // 孩子上移
        child = 2 * child;          // 继续向下调整
    }
    arr[child/2] = temp;
}
完整代码
c 复制代码
void HeapSort(int arr[], int n) {
    int i, temp;
    
    // 1. 构建大顶堆(从最后一个非叶子节点开始)
    for (i = n/2; i >= 1; i--) {
        HeapAdjust(arr, i, n);
    }
    
    // 2. 反复交换堆顶和末尾,并调整
    for (i = n; i > 1; i--) {
        // 交换堆顶和堆尾
        temp = arr[1];
        arr[1] = arr[i];
        arr[i] = temp;
        
        // 调整剩余元素为堆
        HeapAdjust(arr, 1, i-1);
    }
}
执行过程示例
复制代码
初始数组(索引1开始):[49, 38, 65, 97, 76, 13, 27]

第一步:建堆(大顶堆)
原始数组结构(完全二叉树):
        49(1)
       /    \
    38(2)   65(3)
   /   \    /
 97(4) 76(5) 13(6) 27(7)  ← 索引

从i=3开始调整:
i=3: 65与子节点13,27比较,无需交换
i=2: 38与子节点97,76比较,38与97交换 → 数组:49,97,65,38,76,13,27
     38继续与子节点比较,交换后位置4→ 数组:49,97,65,38,76,13,27
i=1: 49与子节点97,65比较,49与97交换 → 数组:97,49,65,38,76,13,27
     49继续与子节点38,76比较,49与76交换 → 数组:97,76,65,38,49,13,27
最终大顶堆:97,76,65,38,49,13,27

第二步:排序
交换97和27 → [27,76,65,38,49,13,97] 调整堆 → [76,49,65,38,27,13,97]
交换76和13 → [13,49,65,38,27,76,97] 调整堆 → [65,49,13,38,27,76,97]
交换65和27 → [27,49,13,38,65,76,97] 调整堆 → [49,38,13,27,65,76,97]
... 直到有序
复杂度分析
  • 时间复杂度
    • 建堆:O(n)(从n/2向下调整)
    • 排序:n-1次调整,每次O(log n) → O(n log n)
    • 总复杂度:O(n log n)
  • 空间复杂度:O(1)(原地排序)
  • 稳定性不稳定(交换堆顶和堆尾可能乱序)
考点解析(高频)
  1. 建堆过程
    • 从最后一个非叶子节点(n/2)开始调整
    • 时间复杂度O(n)要理解(不是O(n log n))
  2. 调整堆过程
    • 下沉操作,每次比较父子节点
    • 时间复杂度O(log n)
  3. 应用场景
    • 不需要全部有序,只要Top K问题(如找最大的10个数)
    • 优先队列的实现
  4. 考试常见题
    • 给定序列,写出建堆后的数组
    • 写出每次交换和调整后的结果
    • 计算堆排序的比较次数

五、归并类排序

5.1 归并排序 ⭐⭐(二路归并)

算法思想

采用分治法,将序列递归地分成两半,分别排序,然后将两个有序子序列合并成一个。

核心操作:合并两个有序序列
c 复制代码
void Merge(int arr[], int temp[], int left, int mid, int right) {
    int i = left;      // 左子序列起点
    int j = mid + 1;   // 右子序列起点
    int k = left;      // 临时数组索引
    
    // 合并两个有序序列
    while (i <= mid && j <= right) {
        if (arr[i] <= arr[j]) {
            temp[k++] = arr[i++];
        } else {
            temp[k++] = arr[j++];
        }
    }
    
    // 处理剩余元素
    while (i <= mid) temp[k++] = arr[i++];
    while (j <= right) temp[k++] = arr[j++];
    
    // 复制回原数组
    for (i = left; i <= right; i++) {
        arr[i] = temp[i];
    }
}
递归版本
c 复制代码
void MergeSort(int arr[], int temp[], int left, int right) {
    if (left < right) {
        int mid = left + (right - left) / 2;
        MergeSort(arr, temp, left, mid);     // 左半排序
        MergeSort(arr, temp, mid + 1, right); // 右半排序
        Merge(arr, temp, left, mid, right);   // 合并
    }
}
非递归(迭代)版本(考试常见)
c 复制代码
void MergeSortIter(int arr[], int n) {
    int* temp = (int*)malloc(n * sizeof(int));
    int len = 1;  // 子序列长度
    
    while (len < n) {
        int i = 0;
        while (i + len < n) {
            int left = i;
            int mid = i + len - 1;
            int right = (i + 2*len - 1 < n-1) ? i + 2*len - 1 : n - 1;
            Merge(arr, temp, left, mid, right);
            i += 2 * len;
        }
        len *= 2;
    }
    free(temp);
}
执行过程示例
复制代码
初始: [49, 38, 65, 97, 76, 13, 27]

分解过程:
[49,38,65,97,76,13,27]
        /          \
[49,38,65,97]   [76,13,27]
    /     \         /    \
[49,38]  [65,97]  [76,13] [27]
  / \      / \      / \     |
[49][38] [65][97] [76][13] [27]

合并过程(自底向上):
[38,49] [65,97] [13,76] [27]
    \      /        \     /
 [38,49,65,97]   [13,27,76]
           \         /
     [13,27,38,49,65,76,97]
复杂度分析
  • 时间复杂度:始终 O(n log n)(划分log n层,每层合并O(n))
  • 空间复杂度:O(n)(需要临时数组)
  • 稳定性稳定(合并时相等元素先取左边)
考点解析
  1. 特点
    • 稳定且时间复杂度稳定(最好最坏都是O(n log n))
    • 空间复杂度较高(缺点)
    • 适合外部排序(大文件排序)
  2. 与快速排序比较
    • 归并稳定,快排不稳定
    • 归并空间O(n) > 快排O(log n)
    • 归并始终O(n log n),快排可能O(n²)
    • 实际快排更快(常数小,缓存友好)
  3. 考试重点
    • 手工模拟归并过程
    • 理解递归和迭代两种实现
    • 空间复杂度计算(易错点)
  4. 外部排序应用:多路归并排序

六、基数排序

6.1 基数排序(多关键字排序)

算法思想

不比较元素大小,而是通过分配和收集进行排序。按位(个位、十位、百位...)进行多次排序。

代码实现(基于计数排序的思想)
c 复制代码
// 获取最大数的位数
int GetMaxBit(int arr[], int n) {
    int max = arr[0];
    for (int i = 1; i < n; i++) {
        if (arr[i] > max) max = arr[i];
    }
    int bits = 0;
    while (max > 0) {
        bits++;
        max /= 10;
    }
    return bits;
}

// 基数排序
void RadixSort(int arr[], int n) {
    int* temp = (int*)malloc(n * sizeof(int));
    int* count = (int*)malloc(10 * sizeof(int));  // 0-9
    int maxBit = GetMaxBit(arr, n);
    int radix = 1;  // 当前位数(1,10,100...)
    
    for (int bit = 1; bit <= maxBit; bit++) {
        // 初始化计数器
        for (int i = 0; i < 10; i++) count[i] = 0;
        
        // 统计当前位的数字出现次数
        for (int i = 0; i < n; i++) {
            int digit = (arr[i] / radix) % 10;
            count[digit]++;
        }
        
        // 计算累积计数(确定每个数字的最终位置)
        for (int i = 1; i < 10; i++) {
            count[i] += count[i-1];
        }
        
        // 从后往前分配(保证稳定性)
        for (int i = n-1; i >= 0; i--) {
            int digit = (arr[i] / radix) % 10;
            temp[count[digit] - 1] = arr[i];
            count[digit]--;
        }
        
        // 复制回原数组
        for (int i = 0; i < n; i++) {
            arr[i] = temp[i];
        }
        
        radix *= 10;
    }
    
    free(temp);
    free(count);
}
执行过程示例
复制代码
初始: [49, 38, 65, 97, 76, 13, 27]

第一趟(按个位):
个位:9,8,5,7,6,3,7
分配:桶0-9
桶3:[13] 桶5:[65] 桶6:[76] 桶7:[97,27] 桶8:[38] 桶9:[49]
收集:13,65,76,97,27,38,49

第二趟(按十位):
十位:1,6,7,9,2,3,4
分配:桶1:[13] 桶2:[27] 桶3:[38] 桶4:[49] 桶6:[65] 桶7:[76] 桶9:[97]
收集:13,27,38,49,65,76,97

结果有序!
复杂度分析
  • 时间复杂度 :O(d(n+r))
    • d:最大位数
    • n:元素个数
    • r:基数(十进制r=10)
  • 空间复杂度:O(n+r)
  • 稳定性稳定
考点解析
  1. 适用场景
    • 整数排序(可推广到字符串、日期)
    • 元素位数d较小(如手机号、身份证号)
  2. 特点
    • 不比较元素大小,效率受位数影响
    • 需要额外空间
    • 稳定排序
  3. 考试重点
    • LSD(最低位优先)和MSD(最高位优先)
    • 手工模拟分配和收集过程
    • 时间复杂度公式理解

七、排序算法比较总结表

算法 最好 平均 最坏 空间 稳定性 适用场景 考试频率
冒泡 O(n) O(n²) O(n²) O(1) 小规模,教学 ⭐⭐
选择 O(n²) O(n²) O(n²) O(1) 小规模,交换代价高 ⭐⭐⭐
插入 O(n) O(n²) O(n²) O(1) 基本有序 ⭐⭐⭐
希尔 O(n^1.3) O(n^1.3) O(n²) O(1) 中等规模 ⭐⭐
快速 O(n log n) O(n log n) O(n²) O(log n) 大规模通用 ⭐⭐⭐⭐⭐
归并 O(n log n) O(n log n) O(n log n) O(n) 外部排序,稳定性要求高 ⭐⭐⭐⭐
O(n log n) O(n log n) O(n log n) O(1) Top K,优先队列 ⭐⭐⭐⭐
基数 O(d(n+r)) O(d(n+r)) O(d(n+r)) O(n+r) 整数/字符串,d较小 ⭐⭐

八、考试题型与例题解析

题型1:手工模拟排序过程

例题:已知序列 {49, 38, 65, 97, 76, 13, 27},写出快速排序第一趟划分后的结果(基准选第一个)。

解析

复制代码
初始:[49, 38, 65, 97, 76, 13, 27]
基准=49,i=0, j=6
① j从右找<49:找到27,arr[0]=27, i=1
② i从左找>49:找到65,arr[6]=65, j=5
③ j继续从右找<49:找到13,arr[1]=13, i=2
④ i从左找>49:找到97,arr[5]=97, j=4
⑤ j继续从右找<49:找到76?76>49,继续找,直到i=j=2
arr[2]=49
结果:[27, 38, 13, 49, 76, 97, 65]

题型2:复杂度分析

例题:对n个元素进行堆排序,在建堆过程中,最多需要多少次比较?

解析

建堆时,每个非叶子节点都要进行下沉调整。总比较次数 ≈ 4n(精确分析可得),即O(n)。具体:高度为h的节点下沉最多比较2h次,求和后约为2n。

题型3:稳定性判断

例题 :判断以下哪些排序算法不稳定?(选择题)

A. 冒泡排序 B. 选择排序 C. 插入排序 D. 归并排序

解析:选择排序不稳定,选B。

题型4:应用场景选择

例题 :若需要在O(n log n)时间内完成排序,且要求稳定性,应选择?

A. 快速排序 B. 堆排序 C. 归并排序 D. 希尔排序

解析:归并排序(C)稳定且时间复杂度O(n log n)。快排和堆排不稳定,希尔不稳定且平均O(n^1.3)。


九、备考建议

  1. 必须手动画出过程

    • 快排的划分过程
    • 归并的合并过程
    • 堆的建堆和调整过程
  2. 牢记复杂度表格

    • 最好、最坏、平均时间复杂度
    • 空间复杂度(特别注意快排O(log n)递归栈)
  3. 稳定性口诀

    • 稳定:插(插入)冒(冒泡)归(归并)基(基数)
    • 口诀:"饽饽酥鸡 "(谐音"剥剥酥鸡"或"伯伯舒基")
      • (冒泡)
      • (归并,取"并"谐音)
      • (插入,英文Sort,或取"插"的韵母)
      • (基数)
  4. 算法实现

    • 堆排序的HeapAdjust最容易写错
    • 快排的Partition有多种写法
    • 归并的Merge必须熟记
  5. 典型考题

    • 每年下午题常考算法填空(堆排序、快速排序)
    • 上午题必考复杂度、稳定性选择题

希望这份详尽的排序算法解析能帮助您顺利通过软考!加油!

相关推荐
AKA__Zas1 小时前
芝士算法(双指针篇 1.0)
java·算法·学习方法
吃着火锅x唱着歌1 小时前
LeetCode 726.原子的数量
linux·算法·leetcode
君义_noip1 小时前
CSP-S 2025 提高级 第一轮(初赛) 阅读程序(3)
c++·算法·信息学奥赛·csp-s 初赛
玛卡巴卡ldf1 小时前
【LeetCode 手撕算法】(栈)有效括号、最小栈、字符串解码、每日温度、柱状图最大矩形
java·数据结构·算法·leetcode·力扣
happyprince1 小时前
05-FlagEmbedding 评估模块详解
算法
wuweijianlove1 小时前
算法优化的多目标平衡与性能建模研究的技术7
算法
_深海凉_1 小时前
LeetCode热题100-两两交换链表中的节点
算法·leetcode·链表
啊罗罗1 小时前
windows下,c++的axv2+fma/avx-vnni加速计算demo
c++·windows·算法
qq_283720051 小时前
Embedding 调优实战技巧:从原理到落地,打造高精度向量检索
python·算法·词嵌入·调优