排序算法学习笔记

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) 不稳定
相关推荐
视觉小萌新7 小时前
AI Class 3 · Chapter 1:变量、字符串、list/dict、if/for(python学习-小白版-有经验可跳过)
python·学习·list
yyyang8810 小时前
蓝牙系统整体架构详解
学习·信息与通信
程序边界10 小时前
一台数据集成软件的拆解笔记(下):一致性、容错、跑批与迁移,KFS 真正难的地方在这
java·前端·笔记
Linux-lucky11 小时前
46-Linux学习之旅之LVS负载均衡与keepalived高可用
linux·运维·学习·ubuntu·负载均衡·lvs
金色光环12 小时前
【DSP学习】C2000_ADC中断_笔记
笔记·学习
Дерек的学习记录12 小时前
Unreal Engine 5:第三人称运动系统和人物动画
开发语言·学习·ue5
zhangrelay12 小时前
mrpt杂乱笔记-26-10-31
笔记·学习
熊猫钓鱼>_>13 小时前
平行视界兼容模式与魔法变量配置避坑【鸿蒙心迹】
运维·服务器·开发语言·笔记·华为·harmonyos·openharmony
衡石科技13 小时前
让多轮问数保持口径一致:Data Agent 的上下文、偏好与学习开关
人工智能·学习·安全
IT199514 小时前
Docker 快速部署 DM8 达梦数据库|完整踩坑笔记
笔记·docker·容器