排序算法-C语言

// 排序算法

//排序算法测试流程
//指定数列 c
//随机生成多少个从多少到多少的数
//输出排序前的数,输出排序后的数
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define BOOL int
#define TRUE 1
#define FALSE 0
#define sort bubble_sort // 使用哪种排序

// 随机数模式组件
const BOOL ran = TRUE;      // 随机模式 开关
const int SIZE_ran = 100;     // 长度
const int RANGE_ran = 100;  // 范围

// 自定义模式
const int SIZE_C = 8;
int c[SIZE_C] = {6,5,3,8,1,2,7,4};

const BOOL RESULT_DISPLAY = TRUE;
const BOOL LITTLE = FALSE;   // 小步骤后公屏 的开关
const BOOL BIG = FALSE;     // 大步骤后公屏 的开关
const BOOL STEP = FALSE;    // 显示步骤
const BOOL TIME = TRUE;     // 显示算法时间的开关
const BOOL CHECK = TRUE;    // 检查数列是否正序



int partition(int arr[],int low, int high);
// 排序函数 一万个
void insertion_sort(int arr[],int size);        // 插入排序 0.219763 0.200803
void half_insertion_sort(int arr[],int size);   // 折半插入排序 0.078195 0.079068
void shell_sort(int arr[], int size);            // 希尔排序 0.002527 0.002765
void bubble_sort(int arr[], int size);          // 冒泡排序 0.277525 0.291703
void quick_sort(int arr[], int size);           // 快速排序 pivot    0.001275
void select_sort(int arr[], int size);          // 选择排序 0.119310
void heap_sort(int arr[], int size);            // 堆排序  0.001395    0.001515
void merge_sort(int arr[], int size);           // 归并排序 0.001811  0.002150


// 外围函数
int display_arr(int arr[],int size);                //打印数组的函数
int* make_ran_arr(int size,int range);              //产生 长度为size的 范围是0~range-1的 随机数
void display_process(BOOL ok,int arr[],int size);   //打印排序过程
int partiton(int arr[],int low, int high);         //快速排序的分段法
void quick_sort_inside(int arr[], int start, int end); //快速排序的内部核心
void check(int arr[], int size);                    // 检查数组是否符合顺序
void build_max_heap(int arr[], int size);           // 建立大根堆
void head_adjust(int add[], int k, int size);       // 调整堆
void merge_sort_inside(int arr[], int low,int high);// 归并排序内置函数
void merge(int arr[], int low,int mid,int high);    //归并排序合并两个函数

/*----------------------- 主函数 -----------------------*/
int main(void){
    int *a = c;
    int SIZE_a = SIZE_C;
    if (ran == TRUE){
        a = make_ran_arr( SIZE_ran, RANGE_ran);
        SIZE_a = SIZE_ran;
    }
    printf("Before sort: ");
//    display_arr(a, SIZE_a);
    sort(a, SIZE_a);
    if (RESULT_DISPLAY == TRUE){
        printf("After sort : ");
        display_arr(a, SIZE_a);
    }
    if (CHECK == TRUE)
        check(a,SIZE_a);
    return 0;
}
/*section---------------------------外围函数-------------------------------------*/
// 打印数组
int display_arr(int arr[],int size){
    int count = 0;
    for (count = 0; count < size - 1; count++){
        printf("%d,",arr[count]);
    }
    printf("%d.
",arr[size-1]);
    return 0;
}

// 随机数数组生成
int* make_ran_arr(int size,int range){
    int* array = (int *)malloc(sizeof(int) * size);
    int count = 0;
    for (count = 0; count < size; count ++){
        array[count] = rand() % range;
    }
    return array;
}

void display_process(BOOL ok,int arr[],int size){
    if (ok == TRUE){
        printf("after one  : ");
        display_arr(arr,size);
    }
}

int partition(int arr[],int low, int high){
    int pivot = arr[low];
    while (low <high){
        while(low <high && arr[high] >=pivot)   high--;
        arr[low] = arr[high];
        while(low <high && arr[low] <= pivot)   low++;
        arr[high] = arr[low];
    }
    arr[low] = pivot;
    return low;
}

void quick_sort_inside(int arr[], int start, int end){
    int pivot = partition(arr,start,end);
    if (start < pivot-1) quick_sort_inside(arr, start, pivot-1);
    if (end > pivot+1) quick_sort_inside(arr, pivot+1, end);
}

void check(int arr[], int size){
    BOOL ok = TRUE;
    int i;
    for (i=0; i <size-1;i++){
        if (arr[i]>arr[i+1]){
            ok = FALSE;
            break;
        }
    }
    if (ok ==TRUE)
        printf("本次排序成功!
");
    else
        printf("本次排序失败!
");
}

void build_max_heap(int *arr, int size){
    for (int i= size/2; i>0; i--){
        head_adjust(arr, i, size);
    }
}


void head_adjust(int arr[], int k, int size_adjust){
    arr[0] = arr[k];
    int i;
    for (i=2*k ; i <= size_adjust ; i*=2){
        if (i+1<= size_adjust && arr[i] <arr[i+1])
            i +=1;
        if (arr[0]>= arr[i])
            break;
        else{
            arr[k] = arr[i];
            k = i;
        }
    }
    arr[k] = arr[0];
}

void merge_sort_inside(int arr[], int low,int high){
    if (low<high){
        int mid = (low+high)/2;
        merge_sort_inside(arr, low, mid);
        merge_sort_inside(arr, mid+1, high);
        merge(arr,low,mid,high);
    }
}

void merge(int arr[], int low,int mid,int high){
    int i,j,k;
    int fuzhu[high-low+1];
    for (k = 0; k <= high-low;k++)  // 填充辅助数组
        fuzhu[k] = arr[k+low];
    for (i = low, j = mid+1, k = i; i<=mid&& j<=high; k++){
        if (fuzhu[i-low] <fuzhu[j-low]){
            arr[k] = fuzhu[i-low];
            i++;
        }
        else{
            arr[k] = fuzhu[j-low];
            j++;
        }
    }
    while (i <= mid){
        arr[k] = fuzhu[i-low];
        k++;
        i++;
    }
    while (j <= high){
        arr[k] = fuzhu[j-low];
        k++;
        j++;
    }
}

/*section---------------------------排序---------------------------------------*/
// 需要提供计时功能
// 需要提供大、小步骤输出函数的功能
//{
//    clock_t start_t,finish_t;
//    start_t = clock();
//    finish_t = clock();
//    if (TIME == TRUE) printf("本次排序用时:%f 秒
",(double)(finish_t-start_t)/CLOCKS_PER_SEC);
//}


// 插入排序
void insertion_sort(int arr[],int size){
    clock_t start_t,finish_t;
    start_t = clock();
    int  count = 0, key = 0;
    for(count = 1; count <size; count++){
        if (STEP == TRUE) printf("前%d个已经排好
",count);
        if (count != 1){
            display_process(BIG, arr, size);
        }
        int i = count - 1;
        for(i = count - 1; i >=0; i--){
            if (arr[i+1] < arr[i]){
                key = arr[i+1];
                arr[i+1] = arr[i];
                arr[i] = key;
                display_process(LITTLE, arr, size);
            }
            else{
                break;
            }
        }
    }
    finish_t = clock();
    if (TIME == TRUE) printf("本次排序用时:%f 秒
",(double)(finish_t-start_t)/CLOCKS_PER_SEC);
}

// 折半插入
void half_insertion_sort(int arr[],int size){
    clock_t start_t,finish_t;
    start_t = clock();
    int i,j,low,high,mid,key;
    for (i=1; i < size; i++){
        if (STEP == TRUE) printf("前%d个已经排好
",i);
        key = arr[i];
        low = 0;
        high = i-1;
        mid = (low +high)/2;
        while (low <= high){
            if (arr[mid] <= key){
                low = mid+1;
                mid = (low +high)/2;
            }else{
                high = mid-1;
                mid = (low +high)/2;
            }
        }
        for (j = i-1; j >= high+1; j--){
            arr[j+1] = arr[j];
        }
        arr[high+1] = key;
        if (i != size-1) display_process(BIG, arr, size);
    }
    finish_t = clock();
    if (TIME == TRUE) printf("本次排序用时:%f 秒
",(double)(finish_t-start_t)/CLOCKS_PER_SEC);
}

// 希尔排序,内部调用折半插入
void shell_sort(int arr[],int size){
    clock_t start_t,finish_t;
    start_t = clock();
    int duanshu,i,j,key;
    for (duanshu = size/2; duanshu>=1; duanshu = duanshu/2 ){
        for (i = duanshu; i < size; i++){
            if (arr[i] < arr[i-duanshu]){
                key = arr[i];
                for (j = i-duanshu; j >= 0 && key <arr[j]; j = j-duanshu){
                    arr[j + duanshu] = arr[j];
                }
                arr[j+duanshu] = key;
                display_process(LITTLE, arr, size);
            }
        }
        display_process(BIG, arr, size);
        if (STEP == TRUE) printf("已经完成段长/组数量 为 %d 的排序
",duanshu);
    }
    finish_t = clock();
    if (TIME == TRUE) printf("本次排序用时:%f 秒
",(double)(finish_t-start_t)/CLOCKS_PER_SEC);
}

// 冒泡排序
void bubble_sort(int arr[], int size){
    clock_t start_t,finish_t;
    start_t = clock();
    int i,j,key;
    for (i = 0; i < size ; i++){
        for (j = size-1; j>i; j--){
            if ( arr[j] < arr[j-1]){
                key = arr[j];
                arr[j] = arr[j-1];
                arr[j-1] =key;
            }
        }
        if (STEP == TRUE) printf("前%d个已经排完了
",i+1);
        display_process(BIG, arr, size);
    }
    finish_t = clock();
    if (TIME == TRUE) printf("本次排序用时:%f 秒
",(double)(finish_t-start_t)/CLOCKS_PER_SEC);
}

void quick_sort(int arr[], int size){
    clock_t start_t,finish_t;
    start_t = clock();
    quick_sort_inside(arr, 0, size-1);
    finish_t = clock();
    if (TIME == TRUE) printf("本次排序用时:%f 秒
",(double)(finish_t-start_t)/CLOCKS_PER_SEC);
}

void select_sort(int arr[], int size){
    clock_t start_t,finish_t;
    start_t = clock();
    int i,j,min,key;
    for (i = 0; i < size-1; i++){
        min = i;
        for (j = i+1; j < size; j++)
            if (arr[j] < arr[min])
            min = j;
        key = arr[min];
        arr[min] = arr[i];
        arr[i] = key;
    }
    finish_t = clock();
    if (TIME == TRUE) printf("本次排序用时:%f 秒
",(double)(finish_t-start_t)/CLOCKS_PER_SEC);
}

void heap_sort(int arr[], int size){
    clock_t start_t,finish_t;
    start_t = clock();
    int new[size+1],i;
    for (i = 1; i<= size; i++)
        new[i] = arr[i-1];
    build_max_heap( new,size);
    for (i = 1; i<size; i ++){
        new[0] = new[1];
        new[1] = new[size - i+1];
        new[size - i+1] = new[0];
        head_adjust(new, 1, size-i);
    }
    for (i =0; i <=size; i++)
        arr[i] = new[i+1];
    finish_t = clock();
    if (TIME == TRUE) printf("本次排序用时:%f 秒
",(double)(finish_t-start_t)/CLOCKS_PER_SEC);
}


void merge_sort(int arr[], int size){
    clock_t start_t,finish_t;
    start_t = clock();
    merge_sort_inside(arr, 0, size-1);
    finish_t = clock();
    if (TIME == TRUE) printf("本次排序用时:%f 秒
",(double)(finish_t-start_t)/CLOCKS_PER_SEC);
}
原文地址:https://www.cnblogs.com/gallien/p/14185997.html