排序算法学习笔记

1. 排序的定义

排序(Sorting)是将一组数据按照一定的顺序排列的过程。排序的顺序可以是升序或降序。

2. 排序算法的分类

排序算法可以分为内部排序和外部排序:

  • 内部排序:数据在内存中进行排序。
  • 外部排序:数据量大于内存容量时,需要借助外部存储进行排序。

3. 常见排序算法

3.1 冒泡排序(Bubble Sort)

冒泡排序是一种简单的交换排序算法,通过重复地遍历要排序的列表,比较相邻元素并交换顺序,直到列表有序。

c 复制代码
void bubbleSort(int* arr, int n) {
    for (int i = 0; i < n - 1; i++) {
        for (int j = 0; j < n - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
}

3.2 选择排序(Selection Sort)

选择排序是一种简单的选择排序算法,通过在未排序部分中找到最小(或最大)元素,并将其放到已排序部分的末尾,直到排序完成。

c 复制代码
void selectionSort(int* arr, int n) {
    for (int i = 0; i < n - 1; i++) {
        int minIndex = i;
        for (int j = i + 1; j < n; j++) {
            if (arr[j] < arr[minIndex]) {
                minIndex = j;
            }
        }
        int temp = arr[minIndex];
        arr[minIndex] = arr[i];
        arr[i] = temp;
    }
}

3.3 插入排序(Insertion Sort)

插入排序是一种简单的插入排序算法,通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

c 复制代码
void insertionSort(int* arr, int n) {
    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];
            j--;
        }
        arr[j + 1] = key;
    }
}

3.4 快速排序(Quick Sort)

快速排序是一种高效的分治排序算法,通过选择一个基准元素,将数组分成两部分,一部分比基准元素小,另一部分比基准元素大,递归地对两部分进行排序。

c 复制代码
int partition(int* arr, int low, int high) {
    int pivot = arr[high];
    int i = low - 1;
    for (int j = low; j <= high - 1; j++) {
        if (arr[j] < pivot) {
            i++;
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
    }
    int temp = arr[i + 1];
    arr[i + 1] = arr[high];
    arr[high] = temp;
    return i + 1;
}

void quickSort(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);
    }
}

3.5 归并排序(Merge Sort)

归并排序是一种高效的分治排序算法,通过将数组分成两个子数组,对每个子数组进行排序,然后合并两个已排序的子数组。

c 复制代码
void merge(int* arr, int l, int m, int r) {
    int n1 = m - l + 1;
    int n2 = r - m;
    int L[n1], R[n2];
    for (int i = 0; i < n1; i++) {
        L[i] = arr[l + i];
    }
    for (int i = 0; i < n2; i++) {
        R[i] = arr[m + 1 + i];
    }
    int i = 0, j = 0, k = l;
    while (i < n1 && j < n2) {
        if (L[i] <= R[j]) {
            arr[k] = L[i];
            i++;
        } else {
            arr[k] = R[j];
            j++;
        }
        k++;
    }
    while (i < n1) {
        arr[k] = L[i];
        i++;
        k++;
    }
    while (j < n2) {
        arr[k] = R[j];
        j++;
        k++;
    }
}

void mergeSort(int* arr, int l, int r) {
    if (l < r) {
        int m = l + (r - l) / 2;
        mergeSort(arr, l, m);
        mergeSort(arr, m + 1, r);
        merge(arr, l, m, r);
    }
}

3.6 堆排序(Heap Sort)

堆排序是一种基于堆这种数据结构的排序算法,通过构建最大堆或最小堆,将堆顶元素与末尾元素交换,然后对剩余元素进行调整,直到排序完成。

c 复制代码
void heapify(int* arr, int n, int i) {
    int largest = i;
    int left = 2 * i + 1;
    int 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) {
        int temp = arr[i];
        arr[i] = arr[largest];
        arr[largest] = temp;
        heapify(arr, n, largest);
    }
}

void heapSort(int* arr, int n) {
    for (int i = n / 2 - 1; i >= 0; i--) {
        heapify(arr, n, i);
    }
    for (int i = n - 1; i > 0; i--) {
        int temp = arr[0];
        arr[0] = arr[i];
        arr[i] = temp;
        heapify(arr, i, 0);
    }
}

4. 排序算法的比较

排序算法 时间复杂度(平均) 时间复杂度(最坏) 时间复杂度(最好) 空间复杂度 稳定性
冒泡排序 O(n^2) O(n^2) O(n) O(1) 稳定
选择排序 O(n^2) O(n^2) O(n^2) O(1) 不稳定
插入排序 O(n^2) O(n^2) O(n) O(1) 稳定
快速排序 O(n log n) O(n^2) O(n log 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) 不稳定
相关推荐
啄缘之间32 分钟前
10.基于 MARCH C+ 算法的SRAM BIST
经验分享·笔记·学习·verilog
石像鬼₧魂石7 小时前
如何配置Fail2Ban的Jail?
linux·学习·ubuntu
hetao17338377 小时前
2025-12-12~14 hetao1733837的刷题笔记
数据结构·c++·笔记·算法
Nan_Shu_6149 小时前
学习:VueUse (1)
学习
Li.CQ9 小时前
SQL学习笔记(二)
笔记·sql·学习
Huangxy__9 小时前
指针的补充学习
学习
Smartdaili China10 小时前
掌握Java网页抓取:技术与示例完整指南
java·网络·学习·指南·网页·住宅ip·爬虫api
自不量力的A同学11 小时前
OpenNJet v3.3.1.3
笔记
charlie11451419112 小时前
如何快速在 VS2026 上使用 C++ 模块 — 完整上手指南
开发语言·c++·笔记·学习·现代c++