所有排序算法,稳定,实现,时间复杂度,示例

✅ 什么是排序的“稳定性”?

稳定排序

如果两个元素在原数组中值相同,排序后它们的相对顺序不变,这种排序就叫稳定排序

不稳定排序

如果排序后,相等元素之间的顺序被打乱了,那就是不稳定排序

好的,下面是最常用的排序算法总结,包括:

  • 算法原理简述
  • 时间复杂度(最优 / 平均 / 最差)
  • 空间复杂度
  • 是否稳定
  • 简单实现(以 C++ 为例)

🧮 常用排序算法对比表

排序算法时间复杂度(最优 / 平均 / 最差)空间复杂度稳定性备注
冒泡排序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 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 log n)(取决于增量序列)O(1)❌ 不稳定插入排序优化
计数排序O(n + k)O(n + k)✅ 稳定只适合整数且范围小
桶排序O(n + k)O(n + k)✅ 稳定倾向于均匀分布
基数排序O(n * d)(d为位数)O(n + k)✅ 稳定用于整数或字符串

🔧 典型排序算法实现(C++)

1. 冒泡排序(Bubble Sort)

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

✅ 稳定,适合入门讲解。


2. 插入排序(Insertion Sort)

void insertionSort(vector<int>& arr) {
    for (int i = 1; i < arr.size(); i++) {
        int key = arr[i], j = i - 1;
        while (j >= 0 && arr[j] > key)
            arr[j + 1] = arr[j--];
        arr[j + 1] = key;
    }
}

✅ 稳定,适合“几乎有序”数组。


3. 归并排序(Merge Sort)

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) / 2;
    mergeSort(arr, l, m);
    mergeSort(arr, m + 1, r);
    merge(arr, l, m, r);
}

✅ 稳定,适合大数据排序。


4. 快速排序(Quick Sort)

int partition(vector<int>& arr, int l, int r) {
    int pivot = arr[r];      // 选最后一个元素作为基准
    int i = l;               // i 指向第一个“大于等于 pivot”的位置

    for (int j = l; j < r; j++) {
        if (arr[j] < pivot) {
            swap(arr[i], arr[j]);
            i++;             // i 往后移,为下一个小于 pivot 的位置
        }
    }

    // 最后将 pivot 放到“中间”正确位置
    swap(arr[i], arr[r]);
    return i;
}

void quickSort(vector<int>& arr, int l, int r) {
    if (l < r) {
        int pi = partition(arr, l, r);
        quickSort(arr, l, pi - 1);
        quickSort(arr, pi + 1, r);
    }
}

❌ 不稳定,但实际中最快,适合大多数通用情况。


5. 堆排序(Heap Sort)

void heapify(vector<int>& arr, int n, int i) {
    int largest = i, l = 2 * i + 1, r = 2 * i + 2;
    if (l < n && arr[l] > arr[largest]) largest = l;
    if (r < n && arr[r] > arr[largest]) largest = r;
    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);
    }
}

❌ 不稳定,常用于优先队列实现。


🧠 小总结:

你要排序的对象推荐算法
小数据、教学冒泡 / 插入
大数据、稳定归并排序
速度优先快速排序
不要求稳定、原地堆排序
整数范围小计数 / 桶排序
整数位数不大基数排序

当然可以!这里我给你列出 每个常用排序算法的示例,包括:

  • 排序前数组
  • 排序后数组
  • 排序过程简单说明(便于理解)

为了统一说明,我们使用同一个例子数组:

原始数组:{5, 2, 9, 1, 5, 6}

✅ 1. 冒泡排序(Bubble Sort)

🔁 原理:

相邻两个元素比较,大的往后“冒泡”

示例过程(部分):

[5, 2, 9, 1, 5, 6]
→ [2, 5, 9, 1, 5, 6]
→ [2, 5, 1, 9, 5, 6]
→ [2, 5, 1, 5, 9, 6]
→ [2, 5, 1, 5, 6, 9] ...

排序后:

[1, 2, 5, 5, 6, 9]

稳定


✅ 2. 选择排序(Selection Sort)

🧠 原理:

每次找最小值放到前面,交换次数少

示例过程(部分):

[5, 2, 9, 1, 5, 6]
→ 选出 1 → [1, 2, 9, 5, 5, 6]
→ 选出 2 → [1, 2, 9, 5, 5, 6]
→ 选出 5 → [1, 2, 5, 9, 5, 6]
→ ...

排序后:

[1, 2, 5, 5, 6, 9]

不稳定


✅ 3. 插入排序(Insertion Sort)

✍️ 原理:

每个元素向前插入到合适位置

示例过程(部分):

[5, 2, 9, 1, 5, 6]
→ 插入2 → [2, 5, 9, 1, 5, 6]
→ 插入9 → [2, 5, 9, 1, 5, 6]
→ 插入1 → [1, 2, 5, 9, 5, 6]
→ 插入5 → [1, 2, 5, 5, 9, 6]
→ 插入6 → [1, 2, 5, 5, 6, 9]

稳定


✅ 4. 归并排序(Merge Sort)

🧩 原理:

分而治之 → 先拆分,再合并排序

拆分过程:

[5,2,9,1,5,6] → [5,2,9] 和 [1,5,6]
→ [5,2] [9] 和 [1] [5,6]
→ ...

合并过程:

[5,2] → [2,5]
[1,5,6] → 合并 → [1,5,6]
最终合并 → [1,2,5,5,6,9]

稳定


✅ 5. 快速排序(Quick Sort)

⚡ 原理:

选一个基准,分成比它小和大的两组递归排

示例过程(部分):

选 pivot = 6
→ 小于6:[5,2,1,5],大于6:[9]
→ 排小组:[5,2,1,5] 递归
→ 最终:[1,2,5,5,6,9]

不稳定


✅ 6. 堆排序(Heap Sort)

🏗️ 原理:

构造最大堆,每次取堆顶放末尾,重新堆化

示例过程(部分):

构建最大堆:9 在堆顶
→ swap(9,6) → [5,2,6,1,5,9]
→ 重新堆化 → 6 在堆顶,再 swap...
→ 最终:[1,2,5,5,6,9]

不稳定


✅ 7. 计数排序(Counting Sort)

🎯 原理:

统计每个元素出现次数,然后按顺序输出

适合:

  • 元素是非负整数
  • 范围小(如 0~100)

示例:

原始数组 [5, 2, 9, 1, 5, 6]

计数数组:

count[1] = 1
count[2] = 1
count[5] = 2
count[6] = 1
count[9] = 1

输出排序结果:

[1, 2, 5, 5, 6, 9]

稳定


✅ 8. 桶排序(Bucket Sort)

🪣 原理:

将数据分到不同区间的桶里,每个桶内部排序,再合并

适合:数据均匀分布

示例:

  • 分桶:{1,2},{5,5,6},{9}
  • 每个桶排序后合并
    [1, 2, 5, 5, 6, 9]

稳定


✅ 9. 基数排序(Radix Sort)

🔢 原理:

从个位到最高位依次排序(适合整数/字符串)

示例(数字按位):

[5,2,9,1,5,6] → 只有一位数,直接按个位排序 → [1,2,5,5,6,9]

多位数例子如 [170, 45, 75, 90, 802]

稳定


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值