排序算法详细介绍对比及备考建议

文章目录

  • 排序算法对比
    • 基本概要
  • 算法逐一介绍
    • 1. 冒泡排序(Bubble Sort)
    • 2. 选择排序(Selection Sort)
    • 3. 插入排序(Insertion Sort)🌟🌟
    • 4. 希尔排序(Shell Sort)
    • 5. 归并排序(Merge Sort)🌟🌟
    • 6. 快速排序(Quick Sort)🌟🌟🌟🌟🌟🌟
    • 7. 堆排序(Heap Sort)🌟🌟
    • 8. 计数排序(Counting Sort)
    • 9. 桶排序(Bucket Sort)
    • 10. 基数排序(Radix Sort)
      • 总结
  • 关于备考
    • ✅ 必考 or 高频排序算法
    • 🎯 企业面试中高频考察点
    • 🧠 拓展建议
    • 🎯 排序算法面试核心知识清单
      • ✅ 高频要求手写的排序算法
    • 🔝 面试高频 Leetcode 题目(附关键词)
    • 🧩 排序面试思维框架(你可以这样答)
      • 🌟 经典问题:快速排序的时间复杂度?
      • 🌟 高级问题:为什么说归并适合链表?
      • 🌟 扩展:非比较类排序的适用场景?
    • 🧠 排序算法复习笔记(面试 & 考试专用)
      • 一、排序算法分类
      • 二、常考排序算法精讲
        • 1. 快速排序(Quick Sort)
        • 2. 归并排序(Merge Sort)
        • 3. 堆排序(Heap Sort)
        • 4. 插入排序(Insertion Sort)
        • 5. 计数排序(Counting Sort)
        • 6. 基数排序(Radix Sort)
      • 三、面试高频题推荐
      • 四、应答框架 & 面试建议
      • 五、实战建议

本文将介绍常见排序算法,包括算法思想、代码实现(C++和Python)、时间复杂度对比及不同排序间的比较。


排序算法对比

基本概要

排序算法大体可分为两种:

  • 比较排序,时间复杂度O(nlogn) ~ O(n^2),主要有:冒泡排序,选择排序,插入排序,归并排序,堆排序,快速排序等。
  • 非比较排序,时间复杂度可以达到O(n),主要有:计数排序,基数排序,桶排序等。
  • 关于排序算法的稳定性问题:排序算法稳定性的简单形式化定义为:如果arr[i] = arr[j],排序前arr[i]arr[j]之前,排序后arr[i]还在arr[j]之前,则称这种排序算法是稳定的。通俗地讲就是保证排序前后两个相等的数的相对顺序不变。(可以通过自定义比较函数来去除稳定性问题)
    举例:对于冒泡排序,原本是稳定的排序算法,如果将记录交换的条件改成arr[i] >= arr[i + 1],则两个相等的记录就会交换位置,从而变成不稳定的排序算法。
排序算法平均时间复杂度最好情况最坏情况空间复杂度稳定性适用场景是否原地
冒泡排序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 log n) ~ O(n²)O(n logn)O(n²)O(1)不稳定中等数据量,通用
归并排序O(n log n)O(n log n)O(n log n)O(n)稳定链表/大数据量,稳定排序
快速排序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(1)不稳定通用排序,避免最坏情况
计数排序O(n +k)O(n +k)O(n +k)O(k)稳定整数,范围小
桶排序O(n +k)O(n +k)O(n²)O(n +k)稳定均匀分布数据,浮点数
基数排序O(d(n +k))O(d(n +k))O(d(n +k))O(n +k)稳定多位数整数

算法逐一介绍

1. 冒泡排序(Bubble Sort)

  • 思想:相邻元素比较交换,将最大元素逐步“冒泡”到末尾。
  • 时间复杂度
    • 平均/最坏:O(n²)
    • 最好(已有序):O(n)
  • 空间复杂度:O(1)
  • 稳定性:稳定

C++代码

void bubbleSort(int arr[], int n) {for (int i = 0; i < n-1; i++) {bool swapped = false;for (int j = 0; j < n-i-1; j++) {if (arr[j] > arr[j+1]) {swap(arr[j], arr[j+1]);swapped = true;}}if (!swapped) break;}
}
//---------------------------
void bubbleSort(vector<int>& arr) {int n = arr.size();for(int i = 0; i < n - 1; ++i)for(int j = 0; j < n - i - 1; ++j)if(arr[j] > arr[j + 1])swap(arr[j], arr[j + 1]);
}

Python代码

def bubble_sort(arr):n = len(arr)for i in range(n-1):swapped = Falsefor j in range(n-i-1):if arr[j] > arr[j+1]:arr[j], arr[j+1] = arr[j+1], arr[j]swapped = Trueif not swapped:breakreturn arr
----------------------------------------
def bubble_sort(arr):n = len(arr)for i in range(n - 1):for j in range(n - i - 1):if arr[j] > arr[j + 1]:arr[j], arr[j + 1] = arr[j + 1], arr[j]

2. 选择排序(Selection Sort)

  • 思想:每次选择最小元素放到已排序序列末尾。
  • 时间复杂度
    • 平均/最好/最坏:O(n²)
  • 空间复杂度:O(1)
  • 稳定性:不稳定

C++代码

void selectionSort(vector<int>& arr) {int n = arr.size();for(int i = 0; i < n - 1; ++i) {int min_idx = i;for(int j = i + 1; j < n; ++j)if(arr[j] < arr[min_idx])min_idx = j;swap(arr[i], arr[min_idx]);}
}

Python代码

def selection_sort(arr):n = len(arr)for i in range(n-1):min_idx = ifor j in range(i+1, n):if arr[j] < arr[min_idx]:min_idx = jarr[i], arr[min_idx] = arr[min_idx], arr[i]return arr

3. 插入排序(Insertion Sort)🌟🌟

  • 思想:逐个将元素插入到已排序序列的正确位置。当前元素向左找合适位置插入。
  • 时间复杂度
    • 平均/最坏:O(n²)
    • 最好(已有序):O(n)
  • 空间复杂度:O(1)
  • 稳定性:稳定

C++代码

void insertionSort(vector<int>& arr) {//int n = arr.size();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--];arr[j + 1] = key;}
}

Python代码

def insertion_sort(arr):for i in range(1, len(arr)):key = arr[i]j = i - 1while j >= 0 and arr[j] > key:arr[j + 1] = arr[j]j -= 1arr[j + 1] = keyreturn arr

4. 希尔排序(Shell Sort)

  • 思想:分组插入排序,逐步缩小间隔。插入排序的优化,分组进行插入。
  • 时间复杂度:O(nlogn) ~ O(n²)(取决于间隔序列)
  • 空间复杂度:O(1)
  • 稳定性:不稳定

C++代码

void shellSort(int arr[], int n) {for (int gap = n/2; gap > 0; gap /= 2) {for (int i = gap; i < n; i++) {int temp = arr[i], j;for (j = i; j >= gap && arr[j-gap] > temp; j -= gap)arr[j] = arr[j-gap];arr[j] = temp;}}
}
----------------------------------------------------
void shellSort(vector<int>& arr) {int n = arr.size();for(int gap = n/2; gap > 0; gap /= 2) {for(int i = gap; i < n; ++i) {int temp = arr[i], j = i;while(j >= gap && arr[j - gap] > temp) {arr[j] = arr[j - gap];j -= gap;}arr[j] = temp;}}
}

Python代码

def shell_sort(arr):n = len(arr)gap = n // 2while gap > 0:for i in range(gap, n):temp = arr[i]j = iwhile j >= gap and arr[j-gap] > temp:arr[j] = arr[j-gap]j -= gaparr[j] = tempgap //= 2return arr

5. 归并排序(Merge Sort)🌟🌟

  • 思想:分治法,递归排序后合并。分而治之,分成小块合并排序。
  • 时间复杂度:O(n log n)
  • 空间复杂度:O(n)
  • 稳定性:稳定
  • 图示:
    在这里插入图片描述
    图源
    C++代码
void merge(int arr[], int l, int m, int r) {int n1 = m - l + 1, n2 = r - m;int L[n1], R[n2];for (int i = 0; i < n1; i++) L[i] = arr[l+i];for (int j = 0; j < n2; j++) R[j] = arr[m+1+j];int i = 0, j = 0, k = l;while (i < n1 && j < n2) {if (L[i] <= R[j]) arr[k++] = L[i++];else arr[k++] = R[j++];}while (i < n1) arr[k++] = L[i++];while (j < n2) arr[k++] = R[j++];
}void mergeSort(int arr[], int l, int r) {if (l >= r) return;int m = l + (r - l)/2;mergeSort(arr, l, m);mergeSort(arr, m+1, r);merge(arr, l, m, r);
}
-----------------------
void merge(vector<int>& arr, int l, int m, int r) {vector<int> left(arr.begin() + l, arr.begin() + m + 1);vector<int> right(arr.begin() + m + 1, arr.begin() + r + 1);int i = 0, j = 0, k = l;while(i < left.size() && j < right.size())arr[k++] = left[i] < right[j] ? left[i++] : right[j++];while(i < left.size()) arr[k++] = left[i++];while(j < right.size()) arr[k++] = right[j++];
}void mergeSort(vector<int>& arr, int l, int r) {if(l >= r) return;int m = l + (r - l) / 2;mergeSort(arr, l, m);mergeSort(arr, m + 1, r);merge(arr, l, m, r);
}

Python代码

def merge_sort(arr):if len(arr) > 1:mid = len(arr) // 2L, R = arr[:mid], arr[mid:]merge_sort(L)merge_sort(R)i = j = k = 0while i < len(L) and j < len(R):if L[i] < R[j]:arr[k] = L[i]i +=1else:arr[k] = R[j]j +=1k +=1while i < len(L):arr[k] = L[i]i +=1; k +=1while j < len(R):arr[k] = R[j]j +=1; k +=1return arr
-----------------------------------------------------
def merge_sort(arr):if len(arr) <= 1:return arrmid = len(arr)//2left = merge_sort(arr[:mid])right = merge_sort(arr[mid:])return merge(left, right)def merge(left, right):result = []i = j = 0while i < len(left) and j < len(right):if left[i] < right[j]:result.append(left[i])i += 1else:result.append(right[j])j += 1result.extend(left[i:])result.extend(right[j:])return result

6. 快速排序(Quick Sort)🌟🌟🌟🌟🌟🌟

  • 思想:分治法,选基准分区,递归排序。选一个基准值,小的放左边,大的放右边。通过一趟排序将待排数据分割成独立的两部分,其中一部分的所有数据都比另一部分小,再递归地对这两部分进行排序。采用“分治”的思想,对于一组数据,选择一个基准元素(base),通常选择第一个或最后一个元素,通过第一轮扫描,比base小的元素都在base左边,比base大的元素都在base右边,再有同样的方法递归排序这两部分,直到序列中所有数据均有序为止。
  • 时间复杂度
    • 平均/最好:O(nlogn)
    • 最坏(已有序):O(n²)
  • 空间复杂度O(log n)(递归栈)
  • 稳定性不稳定
  • 核心步骤
    • 选择基准值(Pivot)
      从数组中选择一个元素作为基准值(pivot),通常选择最后一个元素、第一个元素或随机元素。

    • 分区(Partition)
      将数组重新排列,使得所有小于基准值的元素放在基准值的左侧,所有大于基准值的元素放在右侧。
      分区结束后,基准值的位置即为最终排序后的正确位置。

    • 递归排序
      对基准值左侧和右侧的子数组递归地进行快速排序。

C++代码

int partition(vector<int>& arr, int low, int high) {int pivot = arr[high], i = low - 1;for(int j = low; j < high; ++j) {if(arr[j] <= pivot){i++;swap(arr[i], arr[j]);//swap(arr[++i], arr[j]);}}swap(arr[i + 1], arr[high]);return i + 1;
}void quickSort(vector<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);}
}

Python代码

def quick_sort(arr):if len(arr) <= 1:return arrpivot = arr[-1]left = [x for x in arr[:-1] if x <= pivot]right = [x for x in arr[:-1] if x > pivot]return quick_sort(left) + [pivot] + quick_sort(right)

7. 堆排序(Heap Sort)🌟🌟

  • 思想:构建最大堆,交换堆顶元素并调整堆。利用堆(最大堆)结构,每次取出堆顶元素放到数组尾部。
  • 时间复杂度:O(n log n)
  • 空间复杂度:O(1)
  • 稳定性:不稳定

C++代码

void heapify(vector<int>& arr, int n, int i) {int largest = i, left = 2 * i + 1, 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) {swap(arr[i], arr[largest]);heapify(arr, n, largest);}
}void heapSort(vector<int>& arr) {int n = arr.size();for(int i = n / 2 - 1; i >= 0; --i)heapify(arr, n, i);for(int i = n - 1; i > 0; --i) {swap(arr[0], arr[i]);heapify(arr, i, 0);}
}

Python代码

def heapify(arr, n, i):largest = il, r = 2 * i + 1, 2 * i + 2if l < n and arr[l] > arr[largest]:largest = lif r < n and arr[r] > arr[largest]:largest = rif largest != i:arr[i], arr[largest] = arr[largest], arr[i]heapify(arr, n, largest)def heap_sort(arr):n = len(arr)for i in range(n // 2 - 1, -1, -1):heapify(arr, n, i)for i in range(n - 1, 0, -1):arr[0], arr[i] = arr[i], arr[0]heapify(arr, i, 0)return arr

8. 计数排序(Counting Sort)

  • 思想:统计元素出现次数,按顺序输出。
  • 时间复杂度:O(n + k)(k为数据范围)
  • 空间复杂度:O(k)
  • 稳定性:稳定

C++代码

void countingSort(int arr[], int n, int max_val) {int output[n], count[max_val+1] = {0};for (int i = 0; i < n; i++) count[arr[i]]++;for (int i = 1; i <= max_val; i++) count[i] += count[i-1];for (int i = n-1; i >=0; i--) output[--count[arr[i]]] = arr[i];for (int i = 0; i < n; i++) arr[i] = output[i];
}
-------------------------------------------
void countingSort(vector<int>& arr) {if(arr.empty()) return;int max_val = *max_element(arr.begin(), arr.end());vector<int> count(max_val + 1, 0);for(int num : arr) ++count[num];int index = 0;for(int i = 0; i <= max_val; ++i)while(count[i]--) arr[index++] = i;
}

Python代码

def counting_sort(arr):max_val = max(arr)count = [0] * (max_val + 1)for num in arr:count[num] +=1i = 0for num in range(max_val +1):while count[num] >0:arr[i] = numi +=1count[num] -=1return arr
--------------------------------------------------
def counting_sort(arr):if not arr:returnmax_val = max(arr)count = [0] * (max_val + 1)for num in arr:count[num] += 1idx = 0for i, c in enumerate(count):for _ in range(c):arr[idx] = iidx += 1

9. 桶排序(Bucket Sort)

  • 思想:分桶后分别排序,合并结果。把数据分布到若干桶中,桶内排序,再合并结果。
  • 时间复杂度
    • 平均:O(n + k)
    • 最坏:O(n²)
  • 空间复杂度:O(n + k)
  • 稳定性:稳定(取决于桶内排序算法)

C++代码

void bucketSort(float arr[], int n) {vector<float> buckets[n];for (int i = 0; i < n; i++) {int bi = n * arr[i];buckets[bi].push_back(arr[i]);}for (int i = 0; i < n; i++)sort(buckets[i].begin(), buckets[i].end());int index = 0;for (int i = 0; i < n; i++)for (float num : buckets[i])arr[index++] = num;
}
-----------------------------------------------
void bucketSort(vector<float>& arr) {int n = arr.size();vector<vector<float>> buckets(n);for(float num : arr) {int index = num * n;buckets[index].push_back(num);}for(auto& bucket : buckets)sort(bucket.begin(), bucket.end());arr.clear();for(auto& bucket : buckets)arr.insert(arr.end(), bucket.begin(), bucket.end());
}

Python代码

def bucket_sort(arr):max_val, min_val = max(arr), min(arr)bucket_size = (max_val - min_val) / len(arr)buckets = [[] for _ in range(len(arr))]for num in arr:idx = int((num - min_val) // bucket_size)if idx == len(buckets):idx -=1buckets[idx].append(num)sorted_arr = []for bucket in buckets:sorted_arr.extend(sorted(bucket))return sorted_arr
-------------------------------------------------
def bucket_sort(arr):if len(arr) == 0:returnn = len(arr)buckets = [[] for _ in range(n)]for num in arr:index = int(num * n)buckets[index].append(num)for bucket in buckets:bucket.sort()idx = 0for bucket in buckets:for num in bucket:arr[idx] = numidx += 1

10. 基数排序(Radix Sort)

  • 思想:按位排序,从低位到高位。从低位到高位对数字排序,使用稳定排序如计数排序。
  • 时间复杂度:O(d(n + k))(d为位数)
  • 空间复杂度:O(n + k)
  • 稳定性:稳定

C++代码

void countingSortForRadix(int arr[], int n, int exp) {int output[n], count[10] = {0};for (int i = 0; i < n; i++) count[(arr[i]/exp)%10]++;for (int i = 1; i < 10; i++) count[i] += count[i-1];for (int i = n-1; i >=0; i--) {output[count[(arr[i]/exp)%10]-1] = arr[i];count[(arr[i]/exp)%10]--;}for (int i = 0; i < n; i++) arr[i] = output[i];
}void radixSort(int arr[], int n) {int max_val = *max_element(arr, arr+n);for (int exp = 1; max_val/exp >0; exp *=10)countingSortForRadix(arr, n, exp);
}
--------------------------------
void countingSortByDigit(vector<int>& arr, int exp) {int n = arr.size();vector<int> output(n), count(10, 0);for(int i = 0; i < n; ++i)count[(arr[i] / exp) % 10]++;for(int i = 1; i < 10; ++i)count[i] += count[i - 1];for(int i = n - 1; i >= 0; --i) {output[count[(arr[i] / exp) % 10] - 1] = arr[i];count[(arr[i] / exp) % 10]--;}arr = output;
}void radixSort(vector<int>& arr) {int max_val = *max_element(arr.begin(), arr.end());for(int exp = 1; max_val / exp > 0; exp *= 10)countingSortByDigit(arr, exp);
}

Python代码

def radix_sort(arr):max_val = max(arr)exp = 1while max_val // exp >0:counting_sort_by_digit(arr, exp)exp *=10return arrdef counting_sort_by_digit(arr, exp):n = len(arr)output = [0]*ncount = [0]*10for i in range(n):index = (arr[i] // exp) %10count[index] +=1for i in range(1,10):count[i] += count[i-1]for i in range(n-1, -1, -1):index = (arr[i] // exp) %10output[count[index]-1] = arr[i]count[index] -=1for i in range(n):arr[i] = output[i]
---------------------------------------------------
def counting_sort_by_digit(arr, exp):n = len(arr)output = [0] * ncount = [0] * 10for num in arr:index = (num // exp) % 10count[index] += 1for i in range(1, 10):count[i] += count[i - 1]for num in reversed(arr):index = (num // exp) % 10output[count[index] - 1] = numcount[index] -= 1for i in range(n):arr[i] = output[i]def radix_sort(arr):max_val = max(arr)exp = 1while max_val // exp > 0:counting_sort_by_digit(arr, exp)exp *= 10

总结

  • 冒泡、选择、插入排序:适用于小规模数据。
  • 希尔排序:中等规模数据,优于插入排序。
  • 归并、快速、堆排序:大规模数据,归并稳定但需额外空间,快速排序平均最快,堆排序原地排序。
  • 计数、桶、基数排序:特定场景下高效(如整数范围小、均匀分布、多位数)。

非常好的问题!在数据结构与算法考试、面试(尤其是大厂)中,虽然排序算法很多,但常考的排序算法主要集中在下面这几种,因为它们代表了不同的思想和场景优化策略:


关于备考

✅ 必考 or 高频排序算法

排序算法说明 / 考察点为什么常考
快速排序分治、原地、非稳定排序最常用的高效通用排序,面试常要求手写
归并排序分治、稳定排序、空间换时间经常考在链表中排序(Leetcode经典)
堆排序二叉堆结构、原地排序、优先队列基础常作为Top K 问题基础
插入排序稳定、简单,考察基本理解代码简单,适合考察写基础排序
计数排序线性时间排序代表理解适用范围 + 稳定排序基础
冒泡排序教学用、面试中考“你写一个最基础排序”了解基本交换机制
桶/基数排序高效但场景特定高级笔试题中出现,用于浮点/大数据位排序

🎯 企业面试中高频考察点

  • 写一个快速排序(原地/非递归)
  • 链表使用归并排序排序 O(n log n)
  • 从数据流中找第K大(堆排序)
  • Top K 频率元素(堆 + 计数)
  • 计数排序 vs 比较类排序差别(适用场景)
  • 给定整数数组用基数排序排序

🧠 拓展建议

方向建议练习题
📚 基础写法快速排序、归并排序、堆排序手写
🔍 排序思想比较类 vs 非比较类排序的适用场景
📈 排序优化小数组用插入排序,大数组快速+归并
🧪 Leetcode#215, #912, #148, #347, #451

🎯 排序算法面试核心知识清单

✅ 高频要求手写的排序算法

算法重点考察方向稳定性原地
快速排序分治思想、原地实现、递归/非递归
归并排序分治思想、链表排序实现
堆排序大顶堆构建、Top K 使用
插入排序简单直接、部分有序数组快

🔝 面试高频 Leetcode 题目(附关键词)

题目编号名称涉及排序类型难度
#912排序数组快速/归并排序🟠 中等
#215数组第K大元素快排/堆排序🟠 中等
#347前K高频元素堆 + 计数排序思想🟠 中等
#148链表排序归并排序🔵 困难
#451按频率排序计数 + 自定义排序🟠 中等

🧩 排序面试思维框架(你可以这样答)

🌟 经典问题:快速排序的时间复杂度?

  • 平均:O(n log n)
  • 最坏:O(n²)(已排序数组)
  • 优化:三路快排、随机pivot

🌟 高级问题:为什么说归并适合链表?

  • 不依赖随机访问
  • 可以轻松实现O(1)空间的链表归并
  • 稳定、时间复杂度始终 O(n log n)

🌟 扩展:非比较类排序的适用场景?

  • 计数排序:整数,范围小
  • 基数排序:整数、位数小(如手机号、身份证)
  • 桶排序:小数、浮点数、分布均匀

🧠 排序算法复习笔记(面试 & 考试专用)


一、排序算法分类

分类算法稳定性是否原地时间复杂度(平均)时间复杂度(最坏)适用场景
比较类排序冒泡、插入、选择、归并、快速、堆插入/冒泡/归并 ✅ 其余 ❌归并 ❌ 其余 ✅O(n^2)/O(nlogn)O(n^2)/O(nlogn)通用排序
非比较类排序计数、桶、基数O(n)/O(nk)O(n)/O(nk)整数/位数小/范围有限的排序场景

二、常考排序算法精讲

1. 快速排序(Quick Sort)
  • 思想:分治 + 原地交换
  • 特点:高效,最常用,平均 O(nlogn),最坏 O(n^2)
  • 代码:C++/Python
  • 常考形式:手写实现;找第K大元素;排序 + 去重
2. 归并排序(Merge Sort)
  • 思想:分治 + 合并
  • 特点:稳定,适合链表,空间复杂度 O(n)
  • 常考形式:链表排序;大数据排序
3. 堆排序(Heap Sort)
  • 思想:最大堆构建 + 弹出堆顶
  • 特点:原地,不稳定,优先队列基础
  • 常考形式:Top K 问题,最大/最小K个数
4. 插入排序(Insertion Sort)
  • 思想:构建有序序列,将新元素插入
  • 特点:适合小数组、基本有序场景
5. 计数排序(Counting Sort)
  • 思想:统计频次 -> 回写数组
  • 特点:非比较排序,稳定,O(n+k),适合范围小的整数
6. 基数排序(Radix Sort)
  • 思想:按位排序(低位到高位)
  • 特点:适合大整数排序;与计数结合使用

三、面试高频题推荐

Leetcode 编号题目重点算法
912Sort an Array快排 / 归并
215Kth Largest Element in Array快排 / 堆排序
347Top K Frequent Elements堆 + 计数排序思想
148Sort List归并(链表版)
451Sort Characters by Frequency计数 + 自定义排序

四、应答框架 & 面试建议

1. 你知道哪些排序?哪种最好?

  • 分析场景再选:快排适合通用,归并适合链表,计数适合整数范围小

2. 快排最坏时间复杂度?怎么优化?

  • O(n^2),优化方法:随机化 pivot,三路快排

3. 为什么归并适合链表?

  • 链表不能随机访问,归并分治直接分中间节点,合并无需额外数组

4. 如何实现 Top K 问题?

  • 小顶堆维护前 K 个元素,堆排序或快速选择法

五、实战建议

  • 手写练习:快排(原地)、归并(链表)、堆构建
  • 使用库时:记得 sort() 默认用 IntroSort(快排+堆+插入)
  • 注意稳定性、是否原地、空间复杂度等细节

📌 建议每日刷 1-2 道经典题,注重思维过程而非背代码
📌 可搭配可视化工具(如 Visualgo.net)加深理解

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

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

相关文章

Docker华为云创建私人镜像仓库

Docker华为云创建私人镜像仓库 在华为云官网的 产品 中搜索 容器镜像服务 &#xff1a; 或者在其他页面的搜索栏中搜索 容器镜像服务 &#xff1a; 进入到页面后&#xff0c;点击 创建组织 &#xff08;华为云的镜像仓库称为组织&#xff09;&#xff1a; 设置组织名字后&…

微信小程序-自定义toast

微信小程序-自定义toast 微信小程序原生的toast最多能显示两行文字。方案1:方案2 微信小程序原生的toast最多能显示两行文字。 有时候并不能满足业务需求。所以我们需要使用第三方或者自定义。 方案1: 第三方vant-toast 微信小程序下载引入第三方vant之后。 在需要使用的页面…

安卓手游逆向

一、环境安装 1.1、安装Java环境 1.2、安装SDK环境 1.3、安装NDK环境 二、APK 2.1、文件结构 2.2、打包流程 2.3、安装流程 应用安装涉及目录: system/app ----->系统自带的应用程序,获得adb root权限才能删除。 data/app ------->用户程序安装的目录,安装…

VSCode Continue 扩展踩坑记录

Trae 是一款很优秀的 AI 开发工具&#xff0c;但目前支持的平台还较少&#xff0c;比如不支持 Win7&#xff0c;不支持 Linux&#xff0c;为了在这些平台上进行开发&#xff0c;我需要寻找一个替代品。经过网上搜索&#xff0c;选择了 VSCode Continue 扩展&#xff0c;但在使…

Elasticsearch:AI 助理 - 从通才到专才

作者&#xff1a;来自 Elastic Thorben Jndling 在 AI 世界中&#xff0c;关于构建针对特定领域定制的大型语言模型&#xff08;large language models - LLM&#xff09;的话题备受关注 —— 不论是为了更好的安全性、上下文理解、专业能力&#xff0c;还是更高的准确率。这个…

【ARM】MDK烧录提示Error:failed to execute‘ ‘

1、 文档目标 解决在烧录程序的时候&#xff0c;因为选择了错误的烧录方式导致下载失败的情况。 2、 问题场景 在烧录程序的时候出现了提示&#xff1a;“Error&#xff1a;failed to execute ’ ”&#xff08;如图2-1&#xff09;。检测Target->Debug配置发现没有问题&a…

系统分析师(六)-- 计算机网络

概述 TCP/IP 协议族 DNS DHCP 网络规划与设计 逻辑网络设计 物理网络设计 题目 层次化网络设计 网络冗余设计 综合布线系统 IP地址 网络接入技术 其他网络技术应用 物联网

优化运营、降低成本、提高服务质量的智慧物流开源了

智慧物流视频监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒&#xff0c;省去繁琐重复的适配流程&#xff0c;实现芯片、算法、应用的全流程组合&#xff0c;从而大大减少企业级应用约95%的开发成本可通过边缘计算技术…

从One-Hot到TF-IDF:NLP词向量演进解析与业务实战指南(一)

从One-Hot到TF-IDF&#xff1a;词向量演进之路 开场白&#xff1a; 想象一下&#xff0c;你试图用Excel表格分析《红楼梦》的情感倾向——每个字词都是孤立的单元格&#xff0c;计算机看到的只有冰冷的0和1&#xff0c;而“黛玉葬花”的凄美意境却消失得无影无踪。这就是NLP工…

2. kubernetes操作概览

以下是 Kubernetes 的核心操作概览&#xff0c;涵盖常用命令、资源管理和典型场景的操作流程&#xff1a; 1. 核心操作工具 (1) kubectl 命令行工具 Kubernetes 的所有操作均通过 kubectl 实现&#xff0c;常用命令如下&#xff1a; 操作类型命令示例作用说明查看资源状态ku…

从Ampere到Hopper:GPU架构演进对AI模型训练的颠覆性影响

一、GPU架构演进的底层逻辑 AI大模型训练效率的提升始终与GPU架构的迭代深度绑定。从Ampere到Hopper的演进路径中&#xff0c;英伟达通过‌张量核心升级‌、‌显存架构优化‌、‌计算范式革新‌三大技术路线&#xff0c;将LLM&#xff08;大语言模型&#xff09;训练效率提升至…

p2p的发展

PCDN&#xff08;P2P内容分发网络&#xff09;行业目前处于快速发展阶段&#xff0c;面临机遇与挑战并存的局面。 一、发展机遇 技术融合推动 边缘计算与5G普及&#xff1a;5G的高带宽、低延迟特性与边缘计算技术结合&#xff0c;显著提升PCDN性能&#xff0c;降低延迟&#x…

计算机视觉与深度学习 | 视觉里程计(Visual Odometry, VO)学习思路总结

视觉里程计(Visual Odometry, VO)学习思路总结 视觉里程计(VO)是通过摄像头捕获的图像序列估计相机运动轨迹的技术,广泛应用于机器人、自动驾驶和增强现实等领域。以下是一个系统的学习路径,涵盖基础理论、核心算法、工具及实践建议:一、基础理论与数学准备 核心数学工具…

Ubuntu 24.04 中文输入法安装

搜狗输入法&#xff0c;在Ubuntu 24.04上使用失败&#xff0c;安装教程如下 https://shurufa.sogou.com/linux/guide 出现问题的情况&#xff0c;是这个帖子里描述的&#xff1a; https://forum.ubuntu.org.cn/viewtopic.php?t493893 后面通过google拼音输入法解决了&#x…

阿里云 MSE Nacos 发布全新“安全防护”模块,简化安全配置,提升数据保护

作者&#xff1a;张文浩 阿里云在其微服务引擎&#xff08;MSE&#xff09;注册配置中心 Nacos 上正式推出全新“安全防护”功能模块&#xff0c;旨在帮助企业用户有效管理安全状态和降低开启安全相关功能的学习成本&#xff0c;提升微服务架构的安全性。首期推出的“安全防护…

C#核心(23)StringBuilder

前言 我们先前已经了解了String的一些基本规则和常见的用法,今天就来讲一下和string有所区别的StringBulider。 在 C# 中,StringBuilder 类是一个非常有用的工具,特别是在需要频繁修改字符串时。与 String 类型不同,StringBuilder 类提供了一种动态字符串,可以在不创建新…

活动图与流程图的区别与联系:深入理解两种建模工具

目录 前言1. 活动图概述1.1 活动图的定义1.2 活动图的基本构成要素1.3 活动图的应用场景 2. 流程图概述2.1 流程图的定义2.2 流程图的基本构成要素2.3 流程图的应用场景 3. 活动图与流程图的联系4. 活动图与流程图的区别4.1 所属体系不同4.2 表达能力差异4.3 使用目的与语境4.4…

idea运行springboot项目,运行时不能生成target

1&#xff0c;问题 项目本来运行正常&#xff0c;突然重启项目运行时&#xff0c;提醒主类找不到&#xff0c;发现target未生成 2&#xff0c;解决办法 查看.idea里面的文件&#xff0c;正常是下面这样的 如果有缺失&#xff0c;删除.idea里面的文件&#xff0c;清除idea缓…

【unity游戏开发——Animator动画】Animator动画状态机复用——重写动画控制器 Animator Override Controller

注意&#xff1a;考虑到UGUI的内容比较多&#xff0c;我将UGUI的内容分开&#xff0c;并全部整合放在【unity游戏开发——Animator动画】专栏里&#xff0c;感兴趣的小伙伴可以前往逐一查看学习。 文章目录 一、状态机复用是什么&#xff1f;二、实战专栏推荐完结 一、状态机复…

山东大学软件学院创新项目实训(11)之springboot+vue项目接入deepseekAPI

因为该阶段是前后端搭建阶段&#xff0c;所以没有进大模型的专项训练&#xff0c;所以先用老师给的deepseek接口进行代替 且因为前端设计部分非本人负责且还没有提交到github上&#xff0c;所以目前只能先编写一个简易的界面进行功能的测试 首先进行创建model类 然后创建Cha…