七大主流排序算法时间效率比较(基于C语言)

2023-05-16

这段时间在温故一些常见的排序算法,顺手便把常见的一些比较著名的排序算法对同一个目标样本做了个比较。样本存于文件中, 可以根据需要进行替换。我调试的数据量较小,发现简单算法(冒泡,选择,插入)中差异相对明显,令人诧异的是改进算法中归并排序算法的效率比其他算法效率足足低了一个一个数量级。。。是样本量小影响了归并排序效率还是实现归并排序是我的代码出了问题呢?。。。我会在接下来的学习中进一步深究,同时也欢迎各位盆友提出自己的高见。

接下来上代码,包括所有排序算法和比较逻辑的实现,不到500行,也不算大。

//
//  main.c
//  sort_compare
//
//  Created by tianling on 14-3-21.
//  Copyright (c) 2014年 tianling. All rights reserved.
//  简单实现几种排序算法之间的效率比较

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


const int MAXSIZE = 250;//定义排序样本最大长度

/*
 **定义存放样本数据的结构体
 */
typedef struct data{
    int dataArray[MAXSIZE];//定义临时存放排序样本的数组
    int length;
}dataArray;

typedef int status;

/*
 **函数声明
 */
void arrayBegin(dataArray *array);
void bubbleSort(dataArray *array);
void printArray(dataArray *array);
void selectSort(dataArray *array);
void insertSort(dataArray *array);
void shellSort(dataArray *array);
void heapSort(dataArray *array);
void heapAdjust(dataArray *array,int i,int length);
void mergeSort(dataArray *array,dataArray *temArray,int s,int t);
void merge(dataArray *array1,dataArray *array2,int i,int m,int n);
void quickSort(dataArray *array);
void Qsort(dataArray *array,int low,int high);
int Partition(dataArray *array,int low,int high);

status tableList();

status main(int argc, const char * argv[])
{
    int choose;
    dataArray array;
    clock_t start_time,end_time;
    double work_time;
    
    arrayBegin(&array);
    printf("初始数据:\n");
    printArray(&array);
    
    choose = tableList();
    while (choose != 0) {
        switch(choose){
            case 1:
                start_time = clock();//获取程序开始运算时间
                bubbleSort(&array);
                end_time = clock();//获取程序结束运算时间
                
                work_time = (double)end_time - start_time;//计算程序运算时间
                printArray(&array);
                printf("运行时间 %lf ms \n",work_time);
                /*重新构造目标样本*/
                arrayBegin(&array);
                break;
                
            case 2:
                start_time = clock();
                selectSort(&array);
                end_time = clock();
                
                work_time = (double)end_time - start_time;
                printArray(&array);
                printf("运行时间 %lf ms \n",work_time);
                arrayBegin(&array);
                break;
                
            case 3:
                start_time = clock();
                insertSort(&array);
                end_time = clock();
                
                work_time = (double)end_time - start_time;
                printArray(&array);
                printf("运行时间 %lf ms \n",work_time);
                arrayBegin(&array);
                break;
                
            case 4:
                start_time = clock();
                shellSort(&array);
                end_time = clock();
                
                work_time = (double)end_time - start_time;
                printArray(&array);
                printf("运行时间 %lf ms \n",work_time);
                arrayBegin(&array);
                break;
                
            case 5:
                start_time = clock();
                heapSort(&array);
                end_time = clock();
                
                work_time = (double)end_time - start_time;
                printArray(&array);
                printf("运行时间 %lf ms \n",work_time);
                arrayBegin(&array);
                break;
                
            case 6:
                start_time = clock();
                mergeSort(&array, &array, 0, 49);
                end_time = clock();
                
                work_time = (double)end_time - start_time;
                printArray(&array);
                printf("运行时间 %lf ms \n",work_time);
                arrayBegin(&array);
                break;
                
            case 7:
                start_time = clock();
                quickSort(&array);
                end_time = clock();
                
                work_time = (double)end_time - start_time;
                printArray(&array);
                printf("运行时间 %lf ms \n",work_time);
                arrayBegin(&array);
                break;

                
            default:
                exit(0);
                break;
                
        }
        
        choose = tableList();
    }

    
    return 0;
}


/*
 **初始化目标序列
 */
void arrayBegin(dataArray *array){
    int i = 0,temp;
    FILE *file;
    
    //从文本中读取排序样本
    if((file = fopen("/Users/tianling/Documents/Data_Structure/sort_compare/sort_compare/data.txt","r")) == NULL){
        printf("文件读取失败!");
        return;
    }
    
    array->length = 0;//初始化目标样本长度
    
    while((fscanf(file,"%d",&temp)) != EOF ){
        array->dataArray[i] = temp;
        i++;
        array->length++;
    }
    
    fclose(file);//关闭文件
}


/*
 **冒泡法排序
 */
void bubbleSort(dataArray *array){
    int i,j,change;
    
    for(i = 0;i<array->length;i++){
        for(j = array->length-2;j>=i;j--){
            
            if(array->dataArray[j]>array->dataArray[j+1]){
                change = array->dataArray[j];
                array->dataArray[j] = array->dataArray[j+1];
                array->dataArray[j+1] = change;
            }
        }
    }
    
}


/*
 **简单选择排序
 */
void selectSort(dataArray *array){
    int i,j,min,change;
    
    for(i = 0;i<array->length;i++){
        min = i;//以首元素为第一个基准
        
        for(j = i+1;j<array->length;j++){
            if(array->dataArray[min] > array->dataArray[j]){
                //若有小于基准的值,则更换基准
                min = j;
            }
        }
        if(i != min){
            //若min与i不想等,则说明找到这趟排序的最小值,交换
            change = array->dataArray[min];
            array->dataArray[min] = array->dataArray[i];
            array->dataArray[i] = change;
        }
    }
}


/*
 **直接插入排序
 */
void insertSort(dataArray *array){
    int i,j,temp;//temp为哨兵元素
    
    for(i = 1;i<array->length;i++){
        
        if(array->dataArray[i]<array->dataArray[i-1]){
            temp = array->dataArray[i];
            
            for(j = i-1;array->dataArray[j]>temp;j--){
                array->dataArray[j+1] = array->dataArray[j];//记录后移
            }
            
            array->dataArray[j+1] = temp;//插入到正确位置
        }
    }
}


/*
 **希尔排序
 */
void shellSort(dataArray *array){
    int i,j,temp;
    int increment = array->length;
    
    do{
        increment = increment/3+1;//定义增量序列
        
        for(i = increment;i<array->length;i++){
            
            if(array->dataArray[i] < array->dataArray[i - increment]){
                temp = array->dataArray[i];//用temp暂存
                
                for(j = i-increment;j>=0 && temp < array->dataArray[j];j-=increment){
                    array->dataArray[j+increment] = array->dataArray[j];//记录后移,寻找插入位置
                    
                }
                array->dataArray[j+increment] = temp;//插入
                
            }
        }
        
        
    }while(increment > 1);
}


/*
 **堆排序
 */
void heapSort(dataArray *array){
    int i,temp;
    
    for(i = array->length/2;i>=0;i--){
        heapAdjust(array, i, array->length);//将目标处理成一个大頂堆
    }
    
    for(i = array->length-1;i>0;i--){
        temp = array->dataArray[0];//将堆顶记录和未经交换的子序列中的最后一个序列交换
        array->dataArray[0] = array->dataArray[i];
        array->dataArray[i] = temp;
        
        heapAdjust(array, 0, i-1);//将剩余序列重新调整为一个大頂堆
    }
}


/*
 **将目标处理成大顶堆
 */
void heapAdjust(dataArray *array,int i,int length){
    int temp,j;
    
    temp = array->dataArray[i];
    for(j = 2*i;j<length;j *= 2){//沿关键字较大的孩子结点向下筛选
        
        if(j<length && array->dataArray[j]<array->dataArray[j+1]){//j为关键字中较大记录的下标
            ++j;
        }
        if(temp >= array->dataArray[j])
            break;
        
        array->dataArray[i] = array->dataArray[j];
        i = j;
    }
    array->dataArray[i] = temp;
}


/*
 **归并排序
 */
void mergeSort(dataArray *array,dataArray *temArray,int s,int t){
    int m;
    dataArray TEMP[MAXSIZE+1];
    
    if(s == t){
        temArray->dataArray[s] = array->dataArray[s];
    }
    else{
        m = (s+t)/2;//将目标序列等分为两个序列
        mergeSort(array, TEMP, s, m);
        mergeSort(array, TEMP, m+1, t);
        
        merge(TEMP,temArray,s,m,t);
        
    }
    
    
}



/*
 **将有序子序列归并为有序结果序列
 */
void merge(dataArray *array1,dataArray *array2,int i,int m,int n){
    int j,k,l;
    
    for(j = m+1,k = i;i<=m && j<=n;k++){
        
        if(array1->dataArray[i]<array1->dataArray[j]){
            array2->dataArray[k] = array1->dataArray[i++];
        }else{
            array2->dataArray[k] = array1->dataArray[j++];
        }
    }
    
    if(i<=m){
        for(l = 0;l<=m-i;l++){
            array2->dataArray[k+l] = array1->dataArray[i+l];
        }
    }
    
    if(j<=n){
        for(l = 0;l<=n-j;l++){
            array2->dataArray[k+l] = array1->dataArray[j+l];
        }
    }
}


/*
 **快速排序
 */
void quickSort(dataArray *array){
    Qsort(array, 0, array->length-1);
}


/*
 **对目标样本中的子序列array(low...high)做快速排序
 */
void Qsort(dataArray *array,int low,int high){
    int pivot;
    
    if(low<high){
        pivot = Partition(array, low, high);//将dataArray[low...high]一分为二,并返回枢轴下标
        
        Qsort(array, low, pivot-1);//递归对低子表进行排序
        Qsort(array, pivot+1, high);//递归对高子表进行排序
   
    }
}


/*
 **交换顺序表dataArray中子表的记录,使枢轴记录到位,并返回其所在位置
 **目标使枢轴两边的元素均不大于(小于)它
 */
int Partition(dataArray *array,int low,int high){
    int pivotKey,temp;
    
    pivotKey = array->dataArray[low];//用子表的第一个记录作为枢轴记录
    
    while(low<high){//从两端交替向中间扫描
        
        while(low<high && array->dataArray[high]>=array->dataArray[pivotKey]){
            high--;
        }
        temp = array->dataArray[high];//将比枢轴小的记录交换到低端
        array->dataArray[high] = array->dataArray[low];
        array->dataArray[low] = temp;
        
        while(low<high && array->dataArray[low]<=array->dataArray[pivotKey]){
            low++;
        }
        temp = array->dataArray[high];//将比枢轴大的记录交换到高端
        array->dataArray[high] = array->dataArray[low];
        array->dataArray[low] = temp;
        
    }
    
    return low;//返回枢轴所在的位置
}

/*
 **打印结果集
 */
void printArray(dataArray *array){
    int i;
    
    for(i = 0;i<array->length;i++){
        printf("%d ",array->dataArray[i]);
    }
    printf(" \n");
}


/*
 **操作菜单
 */
status tableList(){
    int choose;
    
    printf("*******请选择排序类型*******\n");
    printf("*******1.冒泡法排序********\n");
    printf("*******2.简单选择排序*******\n");
    printf("*******3.直接插入排序*******\n");
    printf("*******4.希尔排序***********\n");
    printf("*******5.堆排序*************\n");
    printf("*******6.归并排序***********\n");
    printf("*******7.快速排序***********\n");
    printf("*******0.退出**************\n");
    
    scanf("%d",&choose);
    return choose;
}

接下来是调试结果截图(小样本集,可更换样本文件):


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

七大主流排序算法时间效率比较(基于C语言) 的相关文章

随机推荐

  • 服务器为什么能够稳定可靠运行?

    前几天github服务器故障 xff0c 传言服务器被偷走一度上了热搜 xff0c 后证实传言是P图 xff08 下图为假 xff09 但确实每次大型互联网公司服务器故障都引发了人们的广泛讨论 其中还有不少上了热搜 那么服务器到底是何方神圣
  • Yanmar(洋马)发动机SPN-FMI代码在仪表显示

    分享一个自己在仪表上显示洋马发动机SPN FMI代码过程的记录 1 问 xff1a SPN和FMI什么意思 xff1f 答 xff1a 见SAE J1939 73 5 6 诊断故障码定义 诊断故障代码 xff08 DTC xff09 由4
  • APM调试,地面站随手记

    最近随公司调试4轴和8轴APM多旋翼 xff0c 本文将心得记录下来 xff0c 以备自己和他人查阅 xff0c 水平有限 xff0c 如有错误 xff0c 请不吝赐教 本文不定期更新 xff0c 转载请注明出处 2016 9 8 一 自检
  • 解决同一局域网下不同网段能ping通但是ssh不上服务器的情况

    一 xff1a 问题描述 xff1a 在公司的局域网网络环境下有四个ip网段 xff0c 分别是192 168 1 0 2 0 3 0 5 0 xff0c 服务器用的是5 0网段的 xff0c 而个人电脑用的则是1 0网段的 xff0c 在
  • STM32单片机电源端并联电容的重要性

    如图 xff0c 笔者用TQFP 32 100PIN 0 55MM转直插的转接板焊了一个STM32F207VET6的板子 板上引出了SWD调试接口 xff08 仅占用PA13和PA14 xff09 xff0c USART1串口引脚 xff0
  • Linux信号量常用操作表

    以下函数失败时均返回 1 xff0c 所在头文件为 include lt sys sem h gt 创建用于区分信号量的键值key xff1a key t key 61 ftok 34 foo bar 34 39 a 39 xff0c 第一
  • 一文加强对React的记忆(2021 年 6 月更新),收藏再也不用查看文档、教程了

    我不经常使用 React xff0c 所以每当我需要在 React 中做最小的事情时 xff0c 我都必须查看文档 教程或在论坛上发布问题 这就是我决定做这个记忆辅助工具的原因 xff0c 鉴于我的记忆力不是那么好 xff0c 我想为什么不
  • 13.实现鼠标中断处理

    简介 上节实现了对键盘中断服务子程序的处理和修改优化了中断程序 xff0c 但只是简单的在中断服务子程序中记录断码或通码 xff0c 缓冲区使用效率不高 目标 实现鼠标中断处理 优化中断缓存 pc中8259A中断控制器连接模型如下 1 鼠标
  • 【Linux】在Linux上安装VNC

    有幸能够亲自在服务器上面操作一下 xff0c 这篇博客来说一说 xff0c 如何在Linux上安装VNC 首先要知道的是 xff0c VNC是什么 VNC xff08 Virtual Network Computing xff09 xff0
  • win10开启自带的手机投屏功能方式

    本篇文章主要讲解win10开启自带的手机投屏方式 日期 xff1a 2023年1月15日 作者 xff1a 任聪聪 开启后效果 点击连接 打开连接或通过手机其他网络进行连接 连接步骤 xff1a 步骤一 打开手机端的wifi网络设置 xff
  • TensorFlow学习(三):tf.scatter_nd函数

    scatter nd indices updates shape name 61 None 根据indices将updates散布到新的 xff08 初始为零 xff09 张量 根据索引对给定shape的零张量中的单个值或切片应用稀疏upd
  • text to image(八):《Image Generation from Scene Graphs》

    最近在翻阅文本生成图像的相关工作 xff0c 目前比较新的有突破性的工作是李飞飞工作团队18年cvpr发表的 Image Generation from Scene Graphs 论文地址 xff1a https arxiv org abs
  • text to image(四):《Stackgan》

    继续介绍文本生成图像的相关工作 xff0c 本文给出的是2016年12月10日发表于 arXiv 的文章 Stackgan Text to photo realistic image synthesis with stacked gener
  • text to image(六):《AttnGAN》

    继续介绍文本生成图像的工作 xff0c 本文给出的是CVPR 2018 的文章 AttnGAN Fine Grained Text to Image Generation with Attentional Generative Advers
  • image caption笔记(二):《Show and Tell : A Neural Image Caption Generator》

    一 基本思想 CNN 43 RNN CNN用的是VGG16 RNN部分用的是LSTM 换成resnet101效果会更好 二 模型结构 四 代码分析 xff1a 首先是训练的部分 xff08 1 xff09 准备数据 COCO数据集中的cap
  • L1惩罚项和L2惩罚项

    x即为参数 L2正则化参数 从公式5可以看到 xff0c 越大 xff0c j j衰减得越快 另一个理解可以参考图2 xff0c 越大 xff0c L2圆的半径越小 xff0c 最后求得代价函数最值时各参数也会变得很小
  • COCO数据集介绍

    转载自 xff1a https zhuanlan zhihu com p 29393415 COCO的 全称是Common Objects in COntext xff0c 是微软团队提供的一个可以用来进行图像识别的数据集 MS COCO数
  • image caption笔记(九):《Unsupervised Image Captioning》

    无监督的caption 文章使用一个图像数据集 xff08 MSCOCO xff09 和一个文本语料库 xff08 从Web上抓取的200多万个句子组成图像描述语料库 xff09 来做无监督caption 没有任何配对集合 1 模型结构 x
  • PyTorch中使用指定的GPU

    转载自 http www cnblogs com darkknightzh p 6836568 html PyTorch默认使用从0开始的GPU xff0c 如果GPU0正在运行程序 xff0c 需要指定其他GPU 有如下两种方法来指定需要
  • 七大主流排序算法时间效率比较(基于C语言)

    这段时间在温故一些常见的排序算法 xff0c 顺手便把常见的一些比较著名的排序算法对同一个目标样本做了个比较 样本存于文件中 xff0c 可以根据需要进行替换 我调试的数据量较小 xff0c 发现简单算法 xff08 冒泡 xff0c 选择