打印
[其他]

排序算法效率比较

[复制链接]
51|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
sdlls|  楼主 | 2024-10-31 20:30 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
排序, ar, DA, TI, or, RT
#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 = 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;
            array->dataArray = change;
        }
    }
}


/*
**直接插入排序
*/
void insertSort(dataArray *array){
    int i,j,temp;//temp为哨兵元素

    for(i = 1;i<array->length;i++){

        if(array->dataArray<array->dataArray[i-1]){
            temp = array->dataArray;

            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 < array->dataArray[i - increment]){
                temp = array->dataArray;//用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;
        array->dataArray = temp;

        heapAdjust(array, 0, i-1);//将剩余序列重新调整为一个大頂堆
    }
}


/*
**将目标处理成大顶堆
*/
void heapAdjust(dataArray *array,int i,int length){
    int temp,j;

    temp = array->dataArray;
    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 = array->dataArray[j];
        i = j;
    }
    array->dataArray = temp;
}


/*
**归并排序
*/
void mergeSort(dataArray *array,dataArray *temArray,int s,int t){
    int m;
    dataArray TEMP[MAXSIZE+1];

    if(s == t){
        temArray->dataArray = array->dataArray;
    }
    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<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);
    }
    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;
}


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

34

主题

4810

帖子

1

粉丝