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

本文将介绍常见排序算法,包括算法思想、代码实现(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 = False
        for j in range(n-i-1):
            if arr[j] > arr[j+1]:
                arr[j], arr[j+1] = arr[j+1], arr[j]
                swapped = True
        if not swapped:
            break
    return 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 = i
        for j in range(i+1, n):
            if arr[j] < arr[min_idx]:
                min_idx = j
        arr[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] = arr[j];
            j--;
        arr[j + 1] = key;
    }
}

Python代码

def insertion_sort(arr):
    for i in range(1, len(arr)):
        key = arr[i]
        j = i - 1
        while j >= 0 and arr[j] > key:
            arr[j + 1] = arr[j]
            j -= 1
        arr[j + 1] = key
    return 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 // 2
    while gap > 0:
        for i in range(gap, n):
            temp = arr[i]
            j = i
            while j >= gap and arr[j-gap] > temp:
                arr[j] = arr[j-gap]
                j -= gap
            arr[j] = temp
        gap //= 2
    return 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) // 2
        L, R = arr[:mid], arr[mid:]
        merge_sort(L)
        merge_sort(R)
        i = j = k = 0
        while i < len(L) and j < len(R):
            if L[i] < R[j]:
                arr[k] = L[i]
                i +=1
            else:
                arr[k] = R[j]
                j +=1
            k +=1
        while i < len(L):
            arr[k] = L[i]
            i +=1; k +=1
        while j < len(R):
            arr[k] = R[j]
            j +=1; k +=1
    return arr
-----------------------------------------------------
def merge_sort(arr):
    if len(arr) <= 1:
        return arr
    mid = len(arr)//2
    left = merge_sort(arr[:mid])
    right = merge_sort(arr[mid:])
    return merge(left, right)

def merge(left, right):
    result = []
    i = j = 0
    while i < len(left) and j < len(right):
        if left[i] < right[j]:
            result.append(left[i])
            i += 1
        else:
            result.append(right[j])
            j += 1
    result.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)
      将数组重新排列,使得所有小于基准值的元素放在基准值的左侧,所有大于基准值的元素放在右侧。
      分区结束后,基准值的位置即为最终排序后的正确位置。

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

  • 优化方法:随机化 pivot,三路快排

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);
    }
}
---------------------------------
#include <stack>
//非递归实现
int partition(vector<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++;
            swap(arr[i], arr[j]); // 将小元素交换到左侧区域
        }
    }
    swap(arr[i + 1], arr[high]);  // 将基准放到正确位置
    return i + 1;                 // 返回基准索引
}

void quickSort(vector<int>& arr) {
    if (arr.size() <= 1) return;
    
    stack<pair<int, int>> stk;
    stk.push({0, (int)arr.size() - 1});
    
    while (!stk.empty()) {
        auto [low, high] = stk.top();
        stk.pop();
        
        if (low < high) {
            int pivot = partition(arr, low, high);
            // 先压右区间,再压左区间(栈会反向处理)
            stk.push({pivot + 1, high});
            stk.push({low, pivot - 1});
        }
    }
}

Python代码

def quick_sort(arr):
    if len(arr) <= 1:
        return arr
    pivot = 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 = i
    l, r = 2 * i + 1, 2 * i + 2
    if l < n and arr[l] > arr[largest]:
        largest = l
    if r < n and arr[r] > arr[largest]:
        largest = r
    if 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] +=1
    i = 0
    for num in range(max_val +1):
        while count[num] >0:
            arr[i] = num
            i +=1
            count[num] -=1
    return arr
--------------------------------------------------
def counting_sort(arr):
    if not arr:
        return
    max_val = max(arr)
    count = [0] * (max_val + 1)
    for num in arr:
        count[num] += 1
    idx = 0
    for i, c in enumerate(count):
        for _ in range(c):
            arr[idx] = i
            idx += 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());
}
----------------------------------------------------------
// 整数版本(需要调整桶映射方式)
void bucketSort(vector<int>& arr) {
    if (arr.empty()) return;

    // 找最大值最小值
    int max_val = *max_element(arr.begin(), arr.end());
    int min_val = *min_element(arr.begin(), arr.end());

    // 创建桶(根据数据范围确定桶数)
    const int bucket_count = max_val - min_val + 1;
    vector<vector<int>> buckets(bucket_count);

    // 元素分配到桶中
    for (int num : arr) {
        buckets[num - min_val].push_back(num);
    }

    // 合并桶
    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 -=1
        buckets[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:
        return
    n = 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 = 0
    for bucket in buckets:
        for num in bucket:
            arr[idx] = num
            idx += 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 = 1
    while max_val // exp >0:
        counting_sort_by_digit(arr, exp)
        exp *=10
    return arr

def counting_sort_by_digit(arr, exp):
    n = len(arr)
    output = [0]*n
    count = [0]*10
    for i in range(n):
        index = (arr[i] // exp) %10
        count[index] +=1
    for i in range(1,10):
        count[i] += count[i-1]
    for i in range(n-1, -1, -1):
        index = (arr[i] // exp) %10
        output[count[index]-1] = arr[i]
        count[index] -=1
    for i in range(n):
        arr[i] = output[i]
---------------------------------------------------
def counting_sort_by_digit(arr, exp):
    n = len(arr)
    output = [0] * n
    count = [0] * 10
    for num in arr:
        index = (num // exp) % 10
        count[index] += 1
    for i in range(1, 10):
        count[i] += count[i - 1]
    for num in reversed(arr):
        index = (num // exp) % 10
        output[count[index] - 1] = num
        count[index] -= 1
    for i in range(n):
        arr[i] = output[i]

def radix_sort(arr):
    max_val = max(arr)
    exp = 1
    while 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)
  • 思想:按位排序(低位到高位)
  • 特点:适合大整数排序;与计数结合使用

三、应答框架 & 面试建议

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

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

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

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

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

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

4. 如何实现 Top K 问题?

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

四、实战建议

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值