排序算法的比较

#include "stdio.h " 
#include "stdlib.h " 
#define   Max   100                   //假设文件长度 
typedef   struct{                   //定义记录类型 
        int   key;                         //关键字项 
}RecType; 
typedef   RecType   SeqList[Max+1];   //SeqList为顺序表,表中第0个元素作为哨兵 
int   n;                                   //顺序表实际的长度 
//==========直接插入排序法====== 
void   InsertSort(SeqList   R)   {     //对顺序表R中的记录R[1¨n]按递增序进行插入排序 
        int   i,j; 
        for(i=2;i <=n;i++)                   //依次插入R[2],……,R[n] 
            if(R[i].key <R[i-1].key){   //若R[i].key大于等于有序区中所有的keys,则R[i]留在原位                   R[0]=R[i];j=i-1;             //R[0]是R[i]的副本                   do   {                                     //从右向左在有序区R[1¨i-1]中查找R[i]         的位置                           R[j+1]=R[j];             //将关键字大于R[i].key的记录后移                           j--;                   }while(R[0].key <R[j].key);     //当R[i].key≥R[j].key   是终止 
                R[j+1]=R[0];                                 //R[i]插入到正确的位置上 
        }//endif   
} 
//==========冒泡排序=======   typedef   enum{FALSE,TRUE}   Boolean;     //FALSE为0,TRUE为1 
void   BubbleSort(SeqList   R)   {     //自下向上扫描对R做冒泡排序 
        int   i,j;           
bool   exchange;           //交换标志           for(i=1;i <n;i++)   {         //最多做n-1趟排序 
            exchange=false;           //本趟排序开始前,交换标志应为假 
            for(j=n-1;j> =i;j--){                       //对当前无序区R[i¨n]   自下向上扫描 
                if(R[j+1].key <R[j].key){         //两两比较,满足条件交换记录 
                    R[0]=R[j+1];                             //R[0]不是哨兵,仅做暂存单元 
                    R[j+1]=R[j]; 
                    R[j]=R[0]; 
                    exchange=true;                         //发生了交换,故将交换标志置为真 
        } 
          if(!   exchange)   return;                 //本趟排序未发生交换,提前终止算法 
        }//         endfor(为循环) 
} 
//==========快速排序======= 
//1.========一次划分函数===== 
int   Partition(SeqList   R,int   i,int   j)   { 
        //   对R[i¨j]做一次划分,并返回基准记录的位置 
        RecType   pivot=R[i];               //用第一个记录作为基准 
        while(i <j)   {                             //从区间两端交替向中间扫描,直到i=j 
                  while(i <j   &&R[j].key> =pivot.key)       //基准记录pivot相当与在位置i上 
                        j--;             //从右向左扫描,查找第一个关键字小于pivot.key的记录R[j] 
                if(i <j)               //若找到的R[j].key   <   pivot.key,则 
                                R[i++]=R[j];                                       //交换R[i]和R[j],交换后i指针加1 
                while(i <j   &&R[i].key <=pivot.key)       //基准记录pivot相当与在位置j上 
                                i++;           //从左向右扫描,查找第一个关键字小于pivot.key的记录R[i] 
                if(i <j)             //若找到的R[i].key   >   pivot.key,则 
                                R[j--]=R[i];                                     //交换R[i]和R[j],交换后j指针减1 
        } 
        R[i]=pivot;             //此时,i=j,基准记录已被最后定位 
        return   i;                 //返回基准记录的位置 
} 
//2.=====快速排序=========== 
void   QuickSort(SeqList   R,int   low,int   high)   {   //R[low..high]快速排序 
        int   pivotpos;                         //划分后基准记录的位置 
        if(low <high)   {                       //仅当区间长度大于1时才排序 
            pivotpos=Partition(R,low,high);     //对R[low..high]做一次划分,得到基准记录的位置 
            QuickSort(R,low,pivotpos-1);           //对左区间递归排序 
            QuickSort(R,pivotpos+1,high);         //对右区间递归排序 
        } 
} 
//======直接选择排序======== 
void   SelectSort(SeqList   R)   { 
        int   i,j,k; 
        for(i=1;i <n;i++){                   //做第i趟排序(1≤i≤n-1) 
        k=i; 
                for(j=i+1;j <=n;j++)     //在当前无序区R[i¨n]中选key最小的记录R[k] 
                              if(R[j].key <R[k].key) 
                                k=j;                   //k记下目前找到的最小关键字所在的位置 
                if(k!=i)   {                       //交换R[i]和R[k] 
                              R[0]=R[i];R[i]=R[k];R[k]=R[0]; 
                }   //endif 
        }   //endfor 
} 
//======堆排序======== 
//==========大根堆调整函数======= 
void   Heapify(SeqList   R,int   low,int   high)   {   
      //   将R[low..high]调整为大根堆,除R[low]外,其余结点均满足堆性质 
        int   large;                         //large指向调整结点的左、右孩子结点中关键字较大者 
        RecType   temp=R[low];     //暂存调整结点 
        for(large=2*low;   large <=high;large*=2){     //R[low]是当前调整结点 
            //若large> high,则表示R[low]是叶子,调整结束;否则先令large指向R[low]的左孩子 
                if(large <high   &&   R[large].key <R[large+1].key) 
                                large++;   //若R[low]的右孩子存在且关键字大于左兄弟,则令large指向它 
                //现在R[large]是调整结点R[low]的左右孩子结点中关键字较大者 
        if(temp.key> =R[large].key)     //temp始终对应R[low] 
                        break;     //当前调整结点不小于其孩子结点的关键字,结束调整 
                R[low]=R[large];     //相当于交换了R[low]和R[large] 
                low=large;     //令low指向新的调整结点,相当于temp已筛下到large的位置 
      } 
      R[low]=temp;       //将被调整结点放入最终位置上 
} 
//==========构造大根堆========== 
void   BuildHeap(SeqList   R)   {   //将初始文件R[1..n]构造为堆 
        int   i; 
        for(i=n/2;i> 0;i--) 
        Heapify(R,i,n);             //将R[i..n]调整为大根堆 
} 
//==========堆排序=========== 
void   HeapSort(SeqList   R)   {     //对R[1..n]进行堆排序,不妨用R[0]做暂存单元 
        int   i; 
        BuildHeap(R);                     //将R[1..n]构造为初始大根堆 
        for(i=n;i> 1;i--){             //对当前无序区R[1..i]进行堆排序,共做n-1趟。 
        R[0]=R[1];   R[1]=R[i];R[i]=R[0];           //将堆顶和堆中最后一个记录交换 
                Heapify(R,1,i-1);       //将R[1..i-1]重新调整为堆,仅有R[1]可能违反堆性质。 
        } 
} 
//==========二路归并排序=========== 
//===将两个有序的子序列R[low..m]和R[m+1..high]归并成有序的序列R[low..high]=== 
void   Merge(SeqList   R,int   low,int   m,int   high)   {   
        int   i=low,j=m+1,p=0;   //置初始值 
        RecType   *R1;                   //R1为局部量 
        R1=(RecType   *)malloc((high-low+1)*sizeof(RecType));   //申请空间 
        while(i <=m   &&   j <=high)             //两个子序列非空时取其小者输出到R1[p]上 
        R1[p++]=(R[i].key <=R[j].key)?   R[i++]:R[j++]; 
        while(i <=m)                                   //若第一个子序列非空,则复制剩余记录到R1 
                R1[p++]=R[i++]; 
        while(j <=high)                             //若第二个子序列非空,则复制剩余记录到R1中 
        R1[p++]=R[j++]; 
        for(p=0,i=low;i <=high;p++,i++) 
        R[i]=R1[p];                           //归并完成后将结果复制回R[low..high] 
} 
//=========对R[1..n]做一趟归并排序======== 
void   MergePass(SeqList   R,int   length)   {   
        int   i; 
        for(i=1;i+2*length-1 <=n;i=i+2*length) 
                Merge(R,i,i+length-1,i+2*length-1);   //归并长度为length的两个相邻的子序列 
        if(i+length-1 <n)                             //尚有一个子序列,其中后一个长度小于length 
                Merge(R,i,i+length-1,n);     //归并最后两个子序列 
                //注意:若i≤n且i+length-1≥n时,则剩余一个子序列轮空,无须归并 
} 
//==========   自底向上对R[1..n]做二路归并排序=============== 
void   MergeSort(SeqList   R)   { 
        int   length; 
        for(length=1;length <n;length*=2)           //做[lgn]趟排序 
        MergePass(R,length);                           //有序长度≥n时终止 
} 
//==========输入顺序表======== 
void   input_int(SeqList   R)   {     
        int   i; 
        printf( "Please   input   num(int): "); 
        scanf( "%d ",&n); 
        printf( "Plase   input   %d   integer: ",n); 
        for(i=1;i <=n;i++) 
        scanf( "%d ",&R[i].key); 
} 
//==========输出顺序表======== 
void   output_int(SeqList   R)   { 
        int   i; 
        for(i=1;i <=n;i++) 
        printf( "%4d ",R[i].key); 
} 
//==========主函数====== 
void   main()   { 
        int   i; 
        SeqList   R; 
        input_int(R); 
        printf( "/t********   Select   **********/n "); 
        printf( "/t1:   Insert   Sort/n "); 
        printf( "/t2:   Bubble   Sort/n "); 
        printf( "/t3:   Quick   Sort/n "); 
        printf( "/t4:   Straight   Selection   Sort/n "); 
        printf( "/t5:   Heap   Sort/n "); 
        printf( "/t6:   Merge   Sort/n "); 
        printf( "/t7:   Exit/n "); 
        printf( "/t***************************/n "); 
        scanf( "%d ",&i);       //输入整数1-7,选择排序方式 
        switch   (i){ 
        case   1:   InsertSort(R); 
break;               //值为1,直接插入排序 
        case   2:   BubbleSort(R);   
break;               //值为2,冒泡法排序 
        case   3:   QuickSort(R,1,n);   
break;         //值为3,快速排序 
        case   4:   SelectSort(R);   
break;               //值为4,直接选择排序 
        case   5:   HeapSort(R); 
break;                   //值为5,堆排序 
        case   6:   MergeSort(R);   
break;                 //值为6,归并排序 
        case   7:   exit(0);                                         //值为7,结束程序 
        } 
        printf( "Sort   reult: "); 
        output_int(R); 
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值