Skip to content

排序算法

排序算法是计算机科学中的基础算法,用于将一组数据按照特定顺序排列。本文将详细介绍C语言中常用的排序算法及其实现。

排序算法的基本概念

排序的定义

排序是将一组数据元素按照某个关键字的值的大小,从小到大(升序)或从大到小(降序)排列的过程。

排序算法的分类

按时间复杂度分类

类别时间复杂度算法举例
常数阶O(1)
对数阶O(log n)
线性阶O(n)桶排序、计数排序、基数排序
线性对数阶O(n log n)快速排序、归并排序、堆排序
平方阶O(n²)冒泡排序、选择排序、插入排序
立方阶O(n³)
指数阶O(2ⁿ)

按空间复杂度分类

类别空间复杂度算法举例
原地排序O(1)冒泡排序、选择排序、插入排序、快速排序
非原地排序O(n)归并排序、桶排序、计数排序、基数排序

按稳定性分类

类别定义算法举例
稳定排序相等元素的相对顺序保持不变冒泡排序、插入排序、归并排序、计数排序
不稳定排序相等元素的相对顺序可能改变选择排序、快速排序、堆排序

基本排序算法

1. 冒泡排序 (Bubble Sort)

算法思想

  • 比较相邻的元素,如果前一个比后一个大,就交换它们
  • 对每一对相邻元素执行同样的操作,从开始第一对到结尾的最后一对
  • 每一轮结束后,最大的元素会「冒泡」到数组的末尾
  • 重复以上步骤,每次比较的元素个数减1

实现代码

c
#include <stdio.h>

void bubbleSort(int arr[], int n) {
    for (int i = 0; i < n - 1; i++) {
        // 标记本轮是否发生交换
        int swapped = 0;
        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;
                swapped = 1;
            }
        }
        // 如果本轮没有交换,说明数组已经有序
        if (!swapped) {
            break;
        }
    }
}

void printArray(int arr[], int size) {
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

int main() {
    int arr[] = {64, 34, 25, 12, 22, 11, 90};
    int n = sizeof(arr) / sizeof(arr[0]);
    
    printf("排序前: ");
    printArray(arr, n);
    
    bubbleSort(arr, n);
    
    printf("排序后: ");
    printArray(arr, n);
    
    return 0;
}

算法分析

  • 时间复杂度
    • 最好情况:O(n)(数组已有序)
    • 最坏情况:O(n²)(数组逆序)
    • 平均情况:O(n²)
  • 空间复杂度:O(1)
  • 稳定性:稳定

2. 选择排序 (Selection Sort)

算法思想

  • 首先在未排序序列中找到最小(或最大)元素,存放到排序序列的起始位置
  • 再从剩余未排序元素中继续寻找最小(或最大)元素,放到已排序序列的末尾
  • 重复第二步,直到所有元素均排序完毕

实现代码

c
#include <stdio.h>

void selectionSort(int arr[], int n) {
    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;
            }
        }
        // 交换元素
        if (min_idx != i) {
            int temp = arr[i];
            arr[i] = arr[min_idx];
            arr[min_idx] = temp;
        }
    }
}

void printArray(int arr[], int size) {
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

int main() {
    int arr[] = {64, 25, 12, 22, 11};
    int n = sizeof(arr) / sizeof(arr[0]);
    
    printf("排序前: ");
    printArray(arr, n);
    
    selectionSort(arr, n);
    
    printf("排序后: ");
    printArray(arr, n);
    
    return 0;
}

算法分析

  • 时间复杂度
    • 最好情况:O(n²)
    • 最坏情况:O(n²)
    • 平均情况:O(n²)
  • 空间复杂度:O(1)
  • 稳定性:不稳定

3. 插入排序 (Insertion Sort)

算法思想

  • 将待排序序列分为已排序和未排序两部分
  • 初始时,已排序部分只包含第一个元素
  • 依次将未排序部分的每个元素插入到已排序部分的适当位置
  • 重复第三步,直到未排序部分为空

实现代码

c
#include <stdio.h>

void insertionSort(int arr[], int n) {
    for (int i = 1; i < n; i++) {
        int key = arr[i];
        int j = i - 1;
        
        // 将大于key的元素向右移动
        while (j >= 0 && arr[j] > key) {
            arr[j + 1] = arr[j];
            j--;
        }
        arr[j + 1] = key;
    }
}

void printArray(int arr[], int size) {
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

int main() {
    int arr[] = {12, 11, 13, 5, 6};
    int n = sizeof(arr) / sizeof(arr[0]);
    
    printf("排序前: ");
    printArray(arr, n);
    
    insertionSort(arr, n);
    
    printf("排序后: ");
    printArray(arr, n);
    
    return 0;
}

算法分析

  • 时间复杂度
    • 最好情况:O(n)(数组已有序)
    • 最坏情况:O(n²)(数组逆序)
    • 平均情况:O(n²)
  • 空间复杂度:O(1)
  • 稳定性:稳定

高级排序算法

4. 快速排序 (Quick Sort)

算法思想

  • 选择一个基准元素(通常是第一个或最后一个元素)
  • 将数组分为两部分,小于基准的元素放在左边,大于基准的元素放在右边
  • 对左右两部分递归执行上述步骤
  • 当子数组长度为1或0时,排序完成

实现代码

c
#include <stdio.h>

// 交换元素
void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

// 分区函数
int partition(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(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);
    }
}

void printArray(int arr[], int size) {
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

int main() {
    int arr[] = {10, 7, 8, 9, 1, 5};
    int n = sizeof(arr) / sizeof(arr[0]);
    
    printf("排序前: ");
    printArray(arr, n);
    
    quickSort(arr, 0, n - 1);
    
    printf("排序后: ");
    printArray(arr, n);
    
    return 0;
}

算法分析

  • 时间复杂度
    • 最好情况:O(n log n)(每次分区都将数组均分)
    • 最坏情况:O(n²)(数组已有序或逆序)
    • 平均情况:O(n log n)
  • 空间复杂度:O(log n)(递归调用栈)
  • 稳定性:不稳定

5. 归并排序 (Merge Sort)

算法思想

  • 将数组分成两半
  • 递归地对两半进行排序
  • 将排序好的两半合并成一个有序数组

实现代码

c
#include <stdio.h>
#include <stdlib.h>

// 合并两个有序子数组
void merge(int arr[], int left, int mid, int right) {
    int n1 = mid - left + 1;
    int n2 = right - mid;
    
    // 创建临时数组
    int *L = (int *)malloc(n1 * sizeof(int));
    int *R = (int *)malloc(n2 * sizeof(int));
    
    // 复制数据到临时数组
    for (int i = 0; i < n1; i++) {
        L[i] = arr[left + i];
    }
    for (int j = 0; j < n2; j++) {
        R[j] = arr[mid + 1 + j];
    }
    
    // 合并临时数组
    int i = 0, j = 0, k = left;
    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++;
    }
    
    // 释放临时数组
    free(L);
    free(R);
}

// 归并排序函数
void mergeSort(int arr[], int left, int right) {
    if (left < right) {
        int mid = left + (right - left) / 2;
        
        // 递归排序左右两部分
        mergeSort(arr, left, mid);
        mergeSort(arr, mid + 1, right);
        
        // 合并
        merge(arr, left, mid, right);
    }
}

void printArray(int arr[], int size) {
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

int main() {
    int arr[] = {12, 11, 13, 5, 6, 7};
    int n = sizeof(arr) / sizeof(arr[0]);
    
    printf("排序前: ");
    printArray(arr, n);
    
    mergeSort(arr, 0, n - 1);
    
    printf("排序后: ");
    printArray(arr, n);
    
    return 0;
}

算法分析

  • 时间复杂度
    • 最好情况:O(n log n)
    • 最坏情况:O(n log n)
    • 平均情况:O(n log n)
  • 空间复杂度:O(n)
  • 稳定性:稳定

6. 堆排序 (Heap Sort)

算法思想

  • 将待排序序列构建成一个大顶堆
  • 将堆顶元素(最大值)与末尾元素交换
  • 将剩余n-1个元素重新构建成一个堆
  • 重复步骤2-3,直到整个序列有序

实现代码

c
#include <stdio.h>

// 交换元素
void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

// 调整堆
void heapify(int arr[], int n, int i) {
    int largest = i; // 初始化largest为根
    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) {
        swap(&arr[i], &arr[largest]);
        
        // 递归调整受影响的子堆
        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--) {
        // 将堆顶元素与末尾元素交换
        swap(&arr[0], &arr[i]);
        
        // 调整剩余的堆
        heapify(arr, i, 0);
    }
}

void printArray(int arr[], int size) {
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

int main() {
    int arr[] = {12, 11, 13, 5, 6, 7};
    int n = sizeof(arr) / sizeof(arr[0]);
    
    printf("排序前: ");
    printArray(arr, n);
    
    heapSort(arr, n);
    
    printf("排序后: ");
    printArray(arr, n);
    
    return 0;
}

算法分析

  • 时间复杂度
    • 最好情况:O(n log n)
    • 最坏情况:O(n log n)
    • 平均情况:O(n log n)
  • 空间复杂度:O(1)
  • 稳定性:不稳定

线性时间排序算法

7. 计数排序 (Counting Sort)

算法思想

  • 找出待排序数组中的最大值和最小值
  • 统计数组中每个值为i的元素出现的次数,存入计数数组C的第i项
  • 对所有的计数累加,得到计数数组C
  • 反向填充目标数组

实现代码

c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void countingSort(int arr[], int n) {
    if (n <= 1) {
        return;
    }
    
    // 找出最大值和最小值
    int max = arr[0], min = arr[0];
    for (int i = 1; i < n; i++) {
        if (arr[i] > max) {
            max = arr[i];
        }
        if (arr[i] < min) {
            min = arr[i];
        }
    }
    
    int range = max - min + 1;
    
    // 创建计数数组
    int *count = (int *)calloc(range, sizeof(int));
    if (count == NULL) {
        fprintf(stderr, "内存分配失败\n");
        return;
    }
    
    // 统计每个元素出现的次数
    for (int i = 0; i < n; i++) {
        count[arr[i] - min]++;
    }
    
    // 反向填充原数组
    int index = 0;
    for (int i = 0; i < range; i++) {
        while (count[i] > 0) {
            arr[index++] = i + min;
            count[i]--;
        }
    }
    
    free(count);
}

void printArray(int arr[], int size) {
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

int main() {
    int arr[] = {4, 2, 2, 8, 3, 3, 1};
    int n = sizeof(arr) / sizeof(arr[0]);
    
    printf("排序前: ");
    printArray(arr, n);
    
    countingSort(arr, n);
    
    printf("排序后: ");
    printArray(arr, n);
    
    return 0;
}

算法分析

  • 时间复杂度:O(n + k),其中k是数组中元素的范围
  • 空间复杂度:O(k)
  • 稳定性:稳定

8. 桶排序 (Bucket Sort)

算法思想

  • 将数组分到有限数量的桶里
  • 每个桶再各自排序(可能使用别的排序算法)
  • 最后将各个桶中的元素有序地合并起来

实现代码

c
#include <stdio.h>
#include <stdlib.h>

// 链表节点结构
typedef struct Node {
    int data;
    struct Node *next;
} Node;

// 创建新节点
Node *createNode(int data) {
    Node *newNode = (Node *)malloc(sizeof(Node));
    if (newNode == NULL) {
        fprintf(stderr, "内存分配失败\n");
        exit(1);
    }
    newNode->data = data;
    newNode->next = NULL;
    return newNode;
}

// 插入节点到链表(保持有序)
void insertSorted(Node **head, int data) {
    Node *newNode = createNode(data);
    
    if (*head == NULL || (*head)->data >= data) {
        newNode->next = *head;
        *head = newNode;
        return;
    }
    
    Node *current = *head;
    while (current->next != NULL && current->next->data < data) {
        current = current->next;
    }
    
    newNode->next = current->next;
    current->next = newNode;
}

// 桶排序
void bucketSort(int arr[], int n) {
    if (n <= 1) {
        return;
    }
    
    // 找出最大值
    int max = arr[0];
    for (int i = 1; i < n; i++) {
        if (arr[i] > max) {
            max = arr[i];
        }
    }
    
    // 桶的数量
    int bucketCount = 10;
    
    // 创建桶
    Node **buckets = (Node **)calloc(bucketCount, sizeof(Node *));
    if (buckets == NULL) {
        fprintf(stderr, "内存分配失败\n");
        return;
    }
    
    // 将元素分配到桶中
    for (int i = 0; i < n; i++) {
        int bucketIndex = (arr[i] * bucketCount) / (max + 1);
        insertSorted(&buckets[bucketIndex], arr[i]);
    }
    
    // 从桶中收集元素
    int index = 0;
    for (int i = 0; i < bucketCount; i++) {
        Node *current = buckets[i];
        while (current != NULL) {
            arr[index++] = current->data;
            Node *temp = current;
            current = current->next;
            free(temp);
        }
    }
    
    free(buckets);
}

void printArray(int arr[], int size) {
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

int main() {
    int arr[] = {64, 34, 25, 12, 22, 11, 90};
    int n = sizeof(arr) / sizeof(arr[0]);
    
    printf("排序前: ");
    printArray(arr, n);
    
    bucketSort(arr, n);
    
    printf("排序后: ");
    printArray(arr, n);
    
    return 0;
}

算法分析

  • 时间复杂度
    • 最好情况:O(n + k)
    • 最坏情况:O(n²)
    • 平均情况:O(n + k)
  • 空间复杂度:O(n + k)
  • 稳定性:稳定

9. 基数排序 (Radix Sort)

算法思想

  • 按照低位先排序,然后收集
  • 再按照高位排序,然后再收集
  • 依此类推,直到最高位

实现代码

c
#include <stdio.h>
#include <stdlib.h>

// 获取数组中的最大值
int getMax(int arr[], int n) {
    int max = arr[0];
    for (int i = 1; i < n; i++) {
        if (arr[i] > max) {
            max = arr[i];
        }
    }
    return max;
}

// 计数排序(按指定位数排序)
void countSort(int arr[], int n, int exp) {
    int *output = (int *)malloc(n * sizeof(int));
    int 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];
    }
    
    free(output);
}

// 基数排序
void radixSort(int arr[], int n) {
    int max = getMax(arr, n);
    
    // 对每一位进行计数排序
    for (int exp = 1; max / exp > 0; exp *= 10) {
        countSort(arr, n, exp);
    }
}

void printArray(int arr[], int size) {
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

int main() {
    int arr[] = {170, 45, 75, 90, 802, 24, 2, 66};
    int n = sizeof(arr) / sizeof(arr[0]);
    
    printf("排序前: ");
    printArray(arr, n);
    
    radixSort(arr, n);
    
    printf("排序后: ");
    printArray(arr, n);
    
    return 0;
}

算法分析

  • 时间复杂度:O(d*(n + k)),其中d是位数,k是基数
  • 空间复杂度:O(n + k)
  • 稳定性:稳定

排序算法的比较与选择

排序算法比较表

算法最好时间复杂度最坏时间复杂度平均时间复杂度空间复杂度稳定性
冒泡排序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 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)不稳定
计数排序O(n + k)O(n + k)O(n + k)O(k)稳定
桶排序O(n + k)O(n²)O(n + k)O(n + k)稳定
基数排序O(d(n + k))O(d(n + k))O(d(n + k))O(n + k)稳定

排序算法的选择

根据数据规模选择

  • 小规模数据(n < 100):插入排序、冒泡排序
  • 中等规模数据(100 ≤ n < 10000):快速排序、堆排序
  • 大规模数据(n ≥ 10000):归并排序、桶排序、计数排序、基数排序

根据数据分布选择

  • 基本有序:插入排序、冒泡排序
  • 随机分布:快速排序
  • 分布范围小:计数排序
  • 分布均匀:桶排序
  • 多位数:基数排序

根据内存限制选择

  • 内存充足:归并排序、桶排序、计数排序、基数排序
  • 内存有限:快速排序、堆排序、插入排序、选择排序

排序算法的实际应用

1. 数组排序

c
#include <stdio.h>

// 选择排序实现
void selectionSort(int arr[], int n) {
    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;
            }
        }
        if (min_idx != i) {
            int temp = arr[i];
            arr[i] = arr[min_idx];
            arr[min_idx] = temp;
        }
    }
}

int main() {
    int arr[] = {64, 25, 12, 22, 11};
    int n = sizeof(arr) / sizeof(arr[0]);
    
    printf("排序前: ");
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    
    selectionSort(arr, n);
    
    printf("排序后: ");
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    
    return 0;
}

2. 结构体排序

c
#include <stdio.h>
#include <string.h>

// 学生结构体
typedef struct {
    char name[50];
    int score;
} Student;

// 按分数排序
void sortStudentsByScore(Student students[], int n) {
    for (int i = 0; i < n - 1; i++) {
        for (int j = 0; j < n - i - 1; j++) {
            if (students[j].score > students[j + 1].score) {
                Student temp = students[j];
                students[j] = students[j + 1];
                students[j + 1] = temp;
            }
        }
    }
}

// 按姓名排序
void sortStudentsByName(Student students[], int n) {
    for (int i = 0; i < n - 1; i++) {
        for (int j = 0; j < n - i - 1; j++) {
            if (strcmp(students[j].name, students[j + 1].name) > 0) {
                Student temp = students[j];
                students[j] = students[j + 1];
                students[j + 1] = temp;
            }
        }
    }
}

void printStudents(Student students[], int n) {
    for (int i = 0; i < n; i++) {
        printf("姓名: %s, 分数: %d\n", students[i].name, students[i].score);
    }
}

int main() {
    Student students[] = {
        {"张三", 85},
        {"李四", 92},
        {"王五", 78},
        {"赵六", 90},
        {"钱七", 88}
    };
    int n = sizeof(students) / sizeof(students[0]);
    
    printf("排序前:\n");
    printStudents(students, n);
    
    // 按分数排序
    sortStudentsByScore(students, n);
    printf("\n按分数排序后:\n");
    printStudents(students, n);
    
    // 按姓名排序
    sortStudentsByName(students, n);
    printf("\n按姓名排序后:\n");
    printStudents(students, n);
    
    return 0;
}

3. 链表排序

c
#include <stdio.h>
#include <stdlib.h>

// 链表节点结构
typedef struct Node {
    int data;
    struct Node *next;
} Node;

// 创建新节点
Node *createNode(int data) {
    Node *newNode = (Node *)malloc(sizeof(Node));
    if (newNode == NULL) {
        fprintf(stderr, "内存分配失败\n");
        exit(1);
    }
    newNode->data = data;
    newNode->next = NULL;
    return newNode;
}

// 插入节点到链表末尾
void append(Node **head, int data) {
    Node *newNode = createNode(data);
    
    if (*head == NULL) {
        *head = newNode;
        return;
    }
    
    Node *current = *head;
    while (current->next != NULL) {
        current = current->next;
    }
    current->next = newNode;
}

// 打印链表
void printList(Node *head) {
    Node *current = head;
    while (current != NULL) {
        printf("%d ", current->data);
        current = current->next;
    }
    printf("\n");
}

// 归并两个有序链表
Node *merge(Node *left, Node *right) {
    if (left == NULL) {
        return right;
    }
    if (right == NULL) {
        return left;
    }
    
    Node *result;
    if (left->data <= right->data) {
        result = left;
        result->next = merge(left->next, right);
    } else {
        result = right;
        result->next = merge(left, right->next);
    }
    return result;
}

// 找到链表中间节点
Node *findMiddle(Node *head) {
    if (head == NULL) {
        return head;
    }
    
    Node *slow = head;
    Node *fast = head->next;
    
    while (fast != NULL && fast->next != NULL) {
        slow = slow->next;
        fast = fast->next->next;
    }
    
    return slow;
}

// 链表归并排序
Node *mergeSortList(Node *head) {
    if (head == NULL || head->next == NULL) {
        return head;
    }
    
    // 找到中间节点
    Node *middle = findMiddle(head);
    Node *nextToMiddle = middle->next;
    
    // 分割链表
    middle->next = NULL;
    
    // 递归排序左右两部分
    Node *left = mergeSortList(head);
    Node *right = mergeSortList(nextToMiddle);
    
    // 合并排序后的链表
    return merge(left, right);
}

int main() {
    Node *head = NULL;
    
    // 创建链表
    append(&head, 12);
    append(&head, 11);
    append(&head, 13);
    append(&head, 5);
    append(&head, 6);
    append(&head, 7);
    
    printf("排序前: ");
    printList(head);
    
    head = mergeSortList(head);
    
    printf("排序后: ");
    printList(head);
    
    // 释放链表
    Node *temp;
    while (head != NULL) {
        temp = head;
        head = head->next;
        free(temp);
    }
    
    return 0;
}

总结

排序算法是计算机科学中的基础算法,本文介绍了C语言中常用的排序算法,包括:

基本排序算法:

  1. 冒泡排序:简单直观,适合小规模数据
  2. 选择排序:交换次数少,适合部分有序数据
  3. 插入排序:适合基本有序数据

高级排序算法: 4. 快速排序:平均性能最好,适合大规模随机数据 5. 归并排序:稳定,适合外部排序 6. 堆排序:原地排序,适合大顶堆/小顶堆场景

线性时间排序算法: 7. 计数排序:适合范围小的整数排序 8. 桶排序:适合均匀分布的数据 9. 基数排序:适合多位数排序

选择排序算法的依据:

  • 数据规模
  • 数据分布
  • 内存限制
  • 稳定性要求

通过理解和掌握这些排序算法,你可以根据具体场景选择最合适的排序方法,提高程序的性能和效率。