#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#include<math.h>
#define Max 10000
#define char_len 100
#define Distance 100
int a[Max]={0};
int a2[Max]={0};
int save[Max];
double rt=0.0;
//计算排序时间函数 用到了 函数指针, 可以调用到 随意函数 来计算排序时间
void printTime( void (*sort )(int a[Max] ) , char name[char_len] ){
clock_t tick;
double t;
//实际排序
sort(a);
tick=clock();
//算排序总时间
t=(double)tick/CLK_TCK;
printf( "Total time used of %s is: %lf second\n\n ", name , t-rt);
rt=t;
}
//初始化数组 + 随机函数
void init_array(){
int i=0;
srand((unsigned)time(NULL)); /*随机种子*/
for(i = 1 ; i<Max; i++){
a2[i]=a[i]=rand()*i;
// if( i%100==0)
// printf("\n");
// printf("%d ",a[i]);
}
}
//初始化数组 + 将用a2[] 来恢复 a [] 的值 ,恢复到 开始状态
void init_array2(){
int i=0;
for(i = 1 ; i<Max; i++){
a[i]=a2[i];
}
}
//打印数组
void print_array(){
int i;
for( i=0; i<Max; i++){
if( i%10==0)
printf("\n");
printf("%d ",a[i]);
}
}
/*
第一个算法 : 冒泡排序---------------------------------------------------------------------------
*/
//冒泡 a[] 不解释
void bubble_sort( int a[]){
int i,j,k;
for(i=Max ; i>0 ; i--){
for( j=1; j<i-1;j++){
if( a[j]>a[j+1] ){
k=a[j];
a[j]=a[j+1];
a[j+1]=k;
}
}
}
// print_array();
}
/*
第二个算法 : 直接插入排序---------------------------------------------------------------------------
*/
//插入排序对 a 中 从 left ---> right 的数据排序, 如此设计可提供快排和归并调用
/*
5 1 3 2 4
1 5 3 2 4
1 3 5 2 4
1 2 3 5 4
1 2 3 4 5
*/
void insertionsort(int a[], int left, int right){
int i , j , k ;
for( i=left+1; i<=right; i++){
k= a[i];
for( j = i-1; j>0 ; j--){
if( a[j]> k ){
a[j+1]=a[j];
}else{
// a[j+1]=k;
break;
}
}
a[j+1]=k;
}
}
//插入排序接口
void insert_sort( int a[]){
insertionsort(a , 1, Max-1 );
// print_array();
}
/*
第三个算法 : 简单选择排序---------------------------------------------------------------------------
/*
5 1 3 2 4
1 5 3 2 4
1 2 3 5 4
1 2 3 4 5
*/
int SelectMin( int begin, int end){
int c, b ;
int center= (begin+end)/2;
if( begin<end){
c=SelectMin(begin,center);
b= SelectMin(center+1, end);
return a[c] < a[b] ? c : b ;
}else{
return begin;
}
}
//选择排序主函数, 对 a[] 排序。
void select_sort( int a[]){
int i, j, k,min;
for( i =1; i<Max; i++){
/**/min=0xfffffff;
for(j=i;j<Max; j++){
if(a[j]<min ){
min=a[j];
k=j;
}
}
// k = SelectMin( i,Max-1);
//将每次选择的最小值和前面的数进行对调,数组前半部分有序
if( i!=k ){
j=a[i];
a[i]=a[k];
a[k]=j;
}
}
// print_array();
}
/*
第四个算法 : 希尔排序---------------------------------------------------------------------------
*/
//希尔排序 a, 对 公差为 dk 的 元素排序。
void shell_insert(int a[], int dk){
int i, j , k ;
for(i=dk+1 ; i< Max ; i++){
k=a[i];
for( j= i-dk; j>0 ; j-=dk){
if( a[j]> k ){
a[j+dk]=a[j];
}else{
// a[j+dk]=k;
break;
}
}
a[j+dk]=k;
}
}
//希尔主函数,排序 a[];
void shell_sort( int a[] ){
int k=0;
//确定公差数量
int kp= (int)(log(Max-1)/log(2));
//printf("%d\n",kp);
for( k=0; k<=kp; k++){
//有人统计 希尔的公差为 2^(kp-k)+1 时,效率最高
shell_insert( a,(int)pow(2,kp-k)-1);
}
// print_array();
}
/*
第五个算法 : 堆排序 ---------------------------------------------------------------------------
*/
// 堆的调整函数, s 表示 当前调整的位置, length 表示 调整范围: a [] 的 1--->length 位置,
void heap_adjust( int a[] , int s , int length ){
//确定a[s]是最大元素;s以后的节点都满足这样的定义;
for( i = 2*s ; i<length ; i*=2){
//这里用到 i+1 <length , 不是 i<length , 错了很久,终于搞定了
if( (i+1)<length && a[i]<a[i+1] ) i++;
if( a[i] <= k ) break;
a[s] = a [ i] ;
s = i;
}
a[ s] = k;
}
//堆排主函数, 对 a[] 排序。
void heap_sort( int a[] ){
int i, k;
//对每个非叶节点进行调整(即有孩子的节点)
for( i = (Max-1)/2 ; i>0; i--){
heap_adjust( a, i, Max);
}
//将弹出的最大值放在最后,结果就是从小到大
for( i = Max-1 ; i > 1; i--){
k=a[1];
a[1]=a[i];
}
// print_array();
}
/*
第六个算法 : 归并排序 ---------------------------------------------------------------------------
*/
//合并函数, a 中的 left1 —> right1 , a中的 left2 --> right2 ,进行归并
void merge ( int a[],int left1,int right1,int left2 ,int right2){
int k=0, i , j , m ;
for( i = left1 , j = left2 ; i<= right1 && j <= right2 ; ){
//我这里放了一个错误:a[l1]<a[l2] ==== 费了半小时调试
if(a[i]<a[j])
save[k++]=a[i++];
else
save[k++]=a[j++];
}
while(i<=right1)
save[k++]=a[i++];
while(j<=right2)
save[k++]=a[j++];
for( m= 0 ; m<k; m++){
a[left1++]= save[m];
}
}
// 归并递归函数 , left 和 right ,表示 a[]中的问题规模
void MergeSort(int a[],int left, int right ){
int center=(left + right ) /2;
if(left < right){
MergeSort(a,left,center);
MergeSort(a,center+1,right);
merge(a,left,center,center+1,right);
}
}
//归并 ( 符合函数入口 )
void merge_sort ( int a[] ){
MergeSort( a, 1, Max-1 );
// print_array();
}
/*
第七个算法 : 快速排序---------------------------------------------------------------------------
*/
//交换 a[] 数组下 表 为 h 和 t 的值
void swap( int h, int t){
int k;
k=a[h];
a[h]=a[t];
a[t]=k;
}
// 在 a[] 中 选择 一个比较适合的比较值
int median3(int a[],int left,int right ){
int center =(left + right)/2;
if (a[center]<a[left])
swap(left,center);
if (a[right]<a[left])
swap(left,right);
if (a[right]<a[center])
swap(center,right);
swap(center,right);
return a[right];
}
//快排函数, 对 a[] 中的 left -->right 进行切割分块,递归完成。
void quickSort(int a[],int left,int right){
if (left+Distance <=right) {
int pivot=median3(a,left,right);
int i=left,j=right;
for(;;){
while (a[++i]<pivot){}
while (pivot<a[--j]){}
if (i<j)
swap(i,j);
else
break;
}
swap (i,right);
quickSort(a,left,i-1);
quickSort(a,i+1,right);
}
else
insertionsort(a,left,right);
}
//函数接口
void quick_sort(int a[] ){
quickSort(a,1,Max-1);
// print_array();
}
/*
主函数---------------------------------------------------------------------------
*/
int main(){
init_array();
/*----------------------------------------------
第一段测试代码,建议将Max 调整 10000--100000
目的为:对每个算法的运行都有一个比较
----------------------------------------------*/
printTime( &bubble_sort ," 冒泡算法");
init_array2();
printTime( &insert_sort ,"插入算法");
init_array2();
printTime( &select_sort ,"选择算法");
init_array2();
printTime( &shell_sort ,"希尔算法");
init_array2();
printTime( &heap_sort ,"堆算法 ");
init_array2();
printTime( &merge_sort ,"归并算法");
init_array2();
printTime( &quick_sort ,"快排算法");
/*----------------------------------------------
第二段测试代码,建议将Max 调整 100000--10000000(十万 到 一千万, 后三个可以到一亿)
目的为:对快速算法来个更刺激的比较
----------------------------------------------*/
/*
init_array2();
printTime( &shell_sort ,"希尔算法");
init_array2();
printTime( &heap_sort ,"堆算法 ");
init_array2();
printTime( &merge_sort ,"归并算法");
init_array2();
printTime( &quick_sort ,"快排算法");
*/
/*----------------------------------------------
第三段测试代码,建议将Max 调整 10--100。并将每个算法后
目的为:表示每个算法都是可以的到真确的排序结果
----------------------------------------------*/
/*
init_array2();printf("冒泡算法");
bubble_sort (a);printf("\n");
print_array();
init_array2();printf("\n插入算法");
insert_sort(a);printf("\n");
print_array();
init_array2();printf("\n选择算法");
select_sort(a);printf("\n");
print_array();
init_array2();printf("\n希尔算法");
shell_sort(a);printf("\n");
print_array();
init_array2();printf("\n堆算法 ");
heap_sort(a);printf("\n");
print_array();
init_array2();printf("\n归并算法");
merge_sort(a);printf("\n");
print_array();
init_array2();printf("\n快排算法");
quick_sort(a);printf("\n");
print_array();*/
printf("\n");
return 0;
}
#include<time.h>
#include<stdlib.h>
#include<math.h>
#define Max 10000
#define char_len 100
#define Distance 100
int a[Max]={0};
int a2[Max]={0};
int save[Max];
double rt=0.0;
//计算排序时间函数 用到了 函数指针, 可以调用到 随意函数 来计算排序时间
void printTime( void (*sort )(int a[Max] ) , char name[char_len] ){
clock_t tick;
double t;
//实际排序
sort(a);
tick=clock();
//算排序总时间
t=(double)tick/CLK_TCK;
printf( "Total time used of %s is: %lf second\n\n ", name , t-rt);
rt=t;
}
//初始化数组 + 随机函数
void init_array(){
int i=0;
srand((unsigned)time(NULL)); /*随机种子*/
for(i = 1 ; i<Max; i++){
a2[i]=a[i]=rand()*i;
// if( i%100==0)
// printf("\n");
// printf("%d ",a[i]);
}
}
//初始化数组 + 将用a2[] 来恢复 a [] 的值 ,恢复到 开始状态
void init_array2(){
int i=0;
for(i = 1 ; i<Max; i++){
a[i]=a2[i];
}
}
//打印数组
void print_array(){
int i;
for( i=0; i<Max; i++){
if( i%10==0)
printf("\n");
printf("%d ",a[i]);
}
}
/*
第一个算法 : 冒泡排序---------------------------------------------------------------------------
*/
//冒泡 a[] 不解释
void bubble_sort( int a[]){
int i,j,k;
for(i=Max ; i>0 ; i--){
for( j=1; j<i-1;j++){
if( a[j]>a[j+1] ){
k=a[j];
a[j]=a[j+1];
a[j+1]=k;
}
}
}
// print_array();
}
/*
第二个算法 : 直接插入排序---------------------------------------------------------------------------
*/
//插入排序对 a 中 从 left ---> right 的数据排序, 如此设计可提供快排和归并调用
/*
5 1 3 2 4
1 5 3 2 4
1 3 5 2 4
1 2 3 5 4
1 2 3 4 5
*/
void insertionsort(int a[], int left, int right){
int i , j , k ;
for( i=left+1; i<=right; i++){
k= a[i];
for( j = i-1; j>0 ; j--){
if( a[j]> k ){
a[j+1]=a[j];
}else{
// a[j+1]=k;
break;
}
}
a[j+1]=k;
}
}
//插入排序接口
void insert_sort( int a[]){
insertionsort(a , 1, Max-1 );
// print_array();
}
/*
第三个算法 : 简单选择排序---------------------------------------------------------------------------
*/
//查找最值的 递归函数, 对 begin --- > end 中选择最小值的 下表/*
5 1 3 2 4
1 5 3 2 4
1 2 3 5 4
1 2 3 4 5
*/
int SelectMin( int begin, int end){
int c, b ;
int center= (begin+end)/2;
if( begin<end){
c=SelectMin(begin,center);
b= SelectMin(center+1, end);
return a[c] < a[b] ? c : b ;
}else{
return begin;
}
}
//选择排序主函数, 对 a[] 排序。
void select_sort( int a[]){
int i, j, k,min;
for( i =1; i<Max; i++){
/**/min=0xfffffff;
for(j=i;j<Max; j++){
if(a[j]<min ){
min=a[j];
k=j;
}
}
// k = SelectMin( i,Max-1);
//将每次选择的最小值和前面的数进行对调,数组前半部分有序
if( i!=k ){
j=a[i];
a[i]=a[k];
a[k]=j;
}
}
// print_array();
}
/*
第四个算法 : 希尔排序---------------------------------------------------------------------------
![](https://img-my.csdn.net/uploads/201304/15/1366017706_7498.jpg)
*/
//希尔排序 a, 对 公差为 dk 的 元素排序。
void shell_insert(int a[], int dk){
int i, j , k ;
for(i=dk+1 ; i< Max ; i++){
k=a[i];
for( j= i-dk; j>0 ; j-=dk){
if( a[j]> k ){
a[j+dk]=a[j];
}else{
// a[j+dk]=k;
break;
}
}
a[j+dk]=k;
}
}
//希尔主函数,排序 a[];
void shell_sort( int a[] ){
int k=0;
//确定公差数量
int kp= (int)(log(Max-1)/log(2));
//printf("%d\n",kp);
for( k=0; k<=kp; k++){
//有人统计 希尔的公差为 2^(kp-k)+1 时,效率最高
shell_insert( a,(int)pow(2,kp-k)-1);
}
// print_array();
}
/*
第五个算法 : 堆排序 ---------------------------------------------------------------------------
![](https://img-my.csdn.net/uploads/201304/15/1366017905_7154.gif)
*/
// 堆的调整函数, s 表示 当前调整的位置, length 表示 调整范围: a [] 的 1--->length 位置,
void heap_adjust( int a[] , int s , int length ){
int i ,k;
k = a[s];//确定a[s]是最大元素;s以后的节点都满足这样的定义;
for( i = 2*s ; i<length ; i*=2){
//这里用到 i+1 <length , 不是 i<length , 错了很久,终于搞定了
if( (i+1)<length && a[i]<a[i+1] ) i++;
if( a[i] <= k ) break;
a[s] = a [ i] ;
s = i;
}
a[ s] = k;
}
//堆排主函数, 对 a[] 排序。
void heap_sort( int a[] ){
int i, k;
//对每个非叶节点进行调整(即有孩子的节点)
for( i = (Max-1)/2 ; i>0; i--){
heap_adjust( a, i, Max);
}
//将弹出的最大值放在最后,结果就是从小到大
for( i = Max-1 ; i > 1; i--){
k=a[1];
a[1]=a[i];
a[i]=k;
}
// print_array();
}
/*
第六个算法 : 归并排序 ---------------------------------------------------------------------------
![](https://img-my.csdn.net/uploads/201304/15/1366017789_9088.jpg)
*/
//合并函数, a 中的 left1 —> right1 , a中的 left2 --> right2 ,进行归并
void merge ( int a[],int left1,int right1,int left2 ,int right2){
int k=0, i , j , m ;
for( i = left1 , j = left2 ; i<= right1 && j <= right2 ; ){
//我这里放了一个错误:a[l1]<a[l2] ==== 费了半小时调试
if(a[i]<a[j])
save[k++]=a[i++];
else
save[k++]=a[j++];
}
while(i<=right1)
save[k++]=a[i++];
while(j<=right2)
save[k++]=a[j++];
for( m= 0 ; m<k; m++){
a[left1++]= save[m];
}
}
// 归并递归函数 , left 和 right ,表示 a[]中的问题规模
void MergeSort(int a[],int left, int right ){
int center=(left + right ) /2;
if(left < right){
MergeSort(a,left,center);
MergeSort(a,center+1,right);
merge(a,left,center,center+1,right);
}
}
//归并 ( 符合函数入口 )
void merge_sort ( int a[] ){
MergeSort( a, 1, Max-1 );
// print_array();
}
/*
第七个算法 : 快速排序---------------------------------------------------------------------------
![](https://img-my.csdn.net/uploads/201304/15/1366017872_4107.gif)
*/
//交换 a[] 数组下 表 为 h 和 t 的值
void swap( int h, int t){
int k;
k=a[h];
a[h]=a[t];
a[t]=k;
}
// 在 a[] 中 选择 一个比较适合的比较值
int median3(int a[],int left,int right ){
int center =(left + right)/2;
if (a[center]<a[left])
swap(left,center);
if (a[right]<a[left])
swap(left,right);
if (a[right]<a[center])
swap(center,right);
swap(center,right);
return a[right];
}
//快排函数, 对 a[] 中的 left -->right 进行切割分块,递归完成。
void quickSort(int a[],int left,int right){
if (left+Distance <=right) {
int pivot=median3(a,left,right);
int i=left,j=right;
for(;;){
while (a[++i]<pivot){}
while (pivot<a[--j]){}
if (i<j)
swap(i,j);
else
break;
}
swap (i,right);
quickSort(a,left,i-1);
quickSort(a,i+1,right);
}
else
insertionsort(a,left,right);
}
//函数接口
void quick_sort(int a[] ){
quickSort(a,1,Max-1);
// print_array();
}
/*
主函数---------------------------------------------------------------------------
*/
int main(){
init_array();
/*----------------------------------------------
第一段测试代码,建议将Max 调整 10000--100000
目的为:对每个算法的运行都有一个比较
----------------------------------------------*/
printTime( &bubble_sort ," 冒泡算法");
init_array2();
printTime( &insert_sort ,"插入算法");
init_array2();
printTime( &select_sort ,"选择算法");
init_array2();
printTime( &shell_sort ,"希尔算法");
init_array2();
printTime( &heap_sort ,"堆算法 ");
init_array2();
printTime( &merge_sort ,"归并算法");
init_array2();
printTime( &quick_sort ,"快排算法");
/*----------------------------------------------
第二段测试代码,建议将Max 调整 100000--10000000(十万 到 一千万, 后三个可以到一亿)
目的为:对快速算法来个更刺激的比较
----------------------------------------------*/
/*
init_array2();
printTime( &shell_sort ,"希尔算法");
init_array2();
printTime( &heap_sort ,"堆算法 ");
init_array2();
printTime( &merge_sort ,"归并算法");
init_array2();
printTime( &quick_sort ,"快排算法");
*/
/*----------------------------------------------
第三段测试代码,建议将Max 调整 10--100。并将每个算法后
目的为:表示每个算法都是可以的到真确的排序结果
----------------------------------------------*/
/*
init_array2();printf("冒泡算法");
bubble_sort (a);printf("\n");
print_array();
init_array2();printf("\n插入算法");
insert_sort(a);printf("\n");
print_array();
init_array2();printf("\n选择算法");
select_sort(a);printf("\n");
print_array();
init_array2();printf("\n希尔算法");
shell_sort(a);printf("\n");
print_array();
init_array2();printf("\n堆算法 ");
heap_sort(a);printf("\n");
print_array();
init_array2();printf("\n归并算法");
merge_sort(a);printf("\n");
print_array();
init_array2();printf("\n快排算法");
quick_sort(a);printf("\n");
print_array();*/
printf("\n");
return 0;
}