// 排序算法
//排序算法测试流程
//指定数列 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.\n",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("本次排序成功!\n");
else
printf("本次排序失败!\n");
}
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 秒\n",(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个已经排好\n",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 秒\n",(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个已经排好\n",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 秒\n",(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 的排序\n",duanshu);
}
finish_t = clock();
if (TIME == TRUE) printf("本次排序用时:%f 秒\n",(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个已经排完了\n",i+1);
display_process(BIG, arr, size);
}
finish_t = clock();
if (TIME == TRUE) printf("本次排序用时:%f 秒\n",(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 秒\n",(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 秒\n",(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 秒\n",(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 秒\n",(double)(finish_t-start_t)/CLOCKS_PER_SEC);
}