7种排序

#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();
}
/*
第三个算法 : 简单选择排序---------------------------------------------------------------------------

  */

//查找最值的 递归函数,  对 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();
}

/*
第四个算法 : 希尔排序---------------------------------------------------------------------------

  */

//希尔排序 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 ){

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;


heap_adjust(a, 1, 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;
}
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值