[算法学习笔记]几个排序算法的比较

本文通过实验对比了六种常见的排序算法(插入排序、冒泡排序、选择排序、归并排序、堆排序及快速排序)在不同规模数组上的运行效率。结果显示,在小规模数据上各种算法性能相近,但随着数据规模增大,快速排序展现出显著优势,而冒泡排序等简单算法性能大幅下降。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前面的文章实现了六中排序算法, 分别是插入排序, 冒泡排序, 选择排序, 归并排序, 堆排序以及快速排序
当数组大小为100时它们的表现为:
这里写图片描述
明显看出冒泡和选择算法的速度较慢

当数组大小为1W时:
这里写图片描述
最快的是快排算法, 其次归并排序算法, 对于插入排序来说,面对较大数量时, 性能下降明显

当数组大小为10W时:
这里写图片描述
最快的快速排序算法和最慢的冒泡排序算法差了2000倍

当然每台计算的性能都不同, 所以结果也会有不同, 有兴趣的同学可以自己尝试:

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define MAX_N  100000      // 数组长度

// 冒泡排序
void bubbleSort(int []);
// 插入排序
void insertionSort(int []);
//选择排序
void selectionSort(int []);
// 归并排序
void merge(int [], int, int, int, int []);
void mergeSort(int [], int, int, int []);

// 堆排序
#define PARENT(i) i >> 1            // 取得父节点的下标
#define LEFT(i) i << 1              // 取得左边子节点的下标
#define RIGHT(i) (i << 1) + 1       // 取得右边子节点的下标

void swap(int *, int *);            // 交换函数
void maxHeapify(int [], int);       // 用于维护堆的性质
void bulidMaxHeap(int []);          // 建堆
void heapSort(int []);              // 堆排序

int heapSize = MAX_N;               // 堆大小,排序时自减

// 快速排序(非随机化)
void quickSort(int [], int, int);
int partition(int [], int, int);


int main(){
    int nums[MAX_N], temp[MAX_N];
    int i;
    // 存放带排序的数组
    int bubbleSortArray[MAX_N];
    int insertionSortArray[MAX_N];
    int selectionSortArray[MAX_N];
    int mergeSortArray[MAX_N];
    int heapSortArray[MAX_N];
    int quickSortArray[MAX_N];
    // 用于测试各排序算法的花费时间
    clock_t start, finish;
    double spendTime;

    srand((unsigned)time(0));
    for(i = 0; i < MAX_N; i++){
        nums[i] = rand() % (MAX_N * 2);
        bubbleSortArray[i] = nums[i];
        insertionSortArray[i] = nums[i];
        selectionSortArray[i] = nums[i];
        mergeSortArray[i] = nums[i];
        heapSortArray[i+1] = nums[i];
        quickSortArray[i] = nums[i];
    }

    printf("当前数组大小: %d\n", MAX_N);

    start = clock();
    bubbleSort(bubbleSortArray);
    finish = clock();
    spendTime = (double)(finish - start) / CLOCKS_PER_SEC;
    printf("冒泡排序算法花费时间为%lf秒.\n", spendTime);

    start = clock();
    insertionSort(insertionSortArray);
    finish = clock();
    spendTime = (double)(finish - start) / CLOCKS_PER_SEC;
    printf("插入排序算法花费时间为%lf秒.\n", spendTime);

    start = clock();
    selectionSort(selectionSortArray);
    finish = clock();
    spendTime = (double)(finish - start) / CLOCKS_PER_SEC;
    printf("选择排序算法花费时间为%lf秒.\n", spendTime);

    start = clock();
    mergeSort(mergeSortArray, 0, MAX_N - 1, temp);
    finish = clock();
    spendTime = (double)(finish - start) / CLOCKS_PER_SEC;
    printf("归并排序算法花费时间为%lf秒.\n", spendTime);

    start = clock();
    heapSort(heapSortArray);
    finish = clock();
    spendTime = (double)(finish - start) / CLOCKS_PER_SEC;
    printf("堆排序算法花费时间为%lf秒.\n", spendTime);

    start = clock();
    quickSort(quickSortArray, 0, MAX_N - 1);
    finish = clock();
    spendTime = (double)(finish - start) / CLOCKS_PER_SEC;
    printf("快速排序算法花费时间为%lf秒.\n", spendTime);

    return 0;
}

// 冒泡排序
void bubbleSort(int nums[]){
    int i, j, temp;
    for(i = 0; i < MAX_N - 1; i++){
        for(j = 0; j < MAX_N - 1 - i; j++ ){
            if(nums[j] > nums[j+1]){
                swap(nums + j, nums + j + 1);
            }
        }
    }
}

// 插入排序
void insertionSort(int num[]){
    int i;
    for(i = 1; i < MAX_N; i++){
        int key = num[i];    int j = i - 1;
        while(j >= 0 && num[j] > key){
            num[j + 1] = num[j];
            j--;
        }
        num[j + 1] = key;
    }
}

// 选择排序
void selectionSort(int nums[]){
    int i, j, temp, index;
    for(int i = 0; i < MAX_N - 1; i++){
        index = i;
        for(j = i + 1; j < MAX_N; j++){
            if(nums[j] < nums[index])
                index = j;
        }
        if(index != i){
            temp = nums[i];
            nums[i] = nums[index];
            nums[index] = temp;
        }
    }
}

/*******************
* 归并排序
* array :数组
* left :起始下标值
* mid : 中间下标值
* right : 结束下标值
* temp : 用于存放临时数组
********************/
void merge(int array[], int left, int mid, int right, int temp[]){
    int i = left, j = mid + 1;
    int k = 0;
    while(i <= mid && j <= right){
        if(array[i] < array[j])
            temp[k++] = array[i++];
        else
            temp[k++] = array[j++];
    }

    while(i <= mid)
        temp[k++] = array[i++];

    while(j <= left)
        temp[k++] = array[j++];

    for(i = 0; i < k; i++)
        array[left + i] = temp[i];
}

void mergeSort(int array[], int left, int right, int temp[]){
    if(left < right){
        int mid = (left + right) / 2;
        mergeSort(array, left, mid, temp);
        mergeSort(array, mid + 1, right, temp);
        merge(array, left, mid, right, temp);
    }
}


// 堆排序
void swap(int *a, int *b){
    int temp = *a;
    *a = *b;
    *b = temp;
}

void maxHeapify(int nums[], int i){
    int l = LEFT(i);    // 取得左子节点的下标
    int r = RIGHT(i);   // 取得右子节点的下标
    int largest;        // 当前节点和左右两个子节点中最大的值的下标
    if(l <= heapSize && nums[l] > nums[i])
        largest = l;
    else
        largest = i;
    if(r <= heapSize && nums[r] > nums[largest])
        largest = r;
    if(largest != i){
        swap(nums+i, nums+largest);
        maxHeapify(nums, largest);
    }
}

void bulidMaxHeap(int nums[]){
    int i;
    for(i = MAX_N/2; i >= 1; i--){
        maxHeapify(nums, i);
    }
}


// 快速排序
void heapSort(int nums[]){
    bulidMaxHeap(nums);
    int i;
    heapSize = MAX_N;
    for(i = MAX_N; i >= 2; i--){
        swap(nums + 1, nums + i);
        heapSize--;
        maxHeapify(nums, 1);
    }
}

void quickSort(int nums[], int p, int r){
    if(p < r){
        int q = partition(nums, p, r);
        quickSort(nums, p, q - 1);
        quickSort(nums, q + 1, r);
    }
}

int partition(int nums[], int p, int r){
    int x = nums[r];
    int i = p - 1, j;
    for(j = p; j < r; j++){
        if(nums[j] <= x){
            i++;
            swap(nums+i, nums+j);
        }
    }
    swap(nums+i+1, nums+r);

    return i+1;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值