排序算法(学习笔记),c语言版:

一:插入排序:


一趟直接插入排序算法:
void  StrOnePass(RecType  R[],int i)
{//已知R[1..i-1]中的记录按关键字非递减有序排列,本算法
  //插入R[i],使R[1..i]中的记录按关键字非递减有序排列
       R[0]=R[i]; j=i-1;   //将待排序记录放进监视哨
       x=R[0].key;
       //从后向前查找插入位置,将大于待排序记录向后移动
        while (x< R[j].key)
             { R[j+1]=R[j]; j--; }  //记录后移
         R[j+1]=R[0];     //将待排序记录放到合适位置
} //StrOnePass

void  StrInsSort1(RecType  R[],int n)
{//本算法对R[1..n]进行直接插入排序
   for(i=2;i<=n;i++)        //假定第一个记录有序
      StrOnePass(R, i);
}



直接插入排序的优缺点:
直接插入排序算法简单,当待排序记录数量n很小时,局部有序时,较为适用。当n很大时,其效率不高。



折半插入排序:

void  BinsSort(RecType  R[],int n)
  //对R[1..n]进行折半插入排序
{ for(i=2;i<=n;i++)   //假定第一个记录有序
     { R[0]=R[i];          //将待排记录R[i]暂存到R[0]
       low=1; high=i-1; //设置折半查找的范围               R[low..high]
       while (low<=high)
         {m=(low+high)/2;          //折半
           if(R[0].key< R[m].key)
                   high=m-1;             //插入点在低半区
           else low=m+1;               //插入点在高半区
          }//while
       for (j=i-1; j>high; j--) R[j+1] = R[j]; //记录后移
       R[high+1] = R[0];      //插入
     }//for
}//BinsSort



性能分析:
减少了比较次数,移动次数不变。
时间复杂度仍为O(n2)。

二:冒泡排序:

void   BubbleSort(RecType R[ ],int n) //起泡排序
 { i = n;        //i 指示无序序列中最后一个记录的位置
   while(i>1)
       {LastExchange=1; //记最后一次交换发生的位置
         for(j=1;j<i;j++)     
             if(R[j].key>R[j+1].key)
                 {R[j]?R[j+1];   //逆序时交换                   
                  LastExchange=j;
                 }//if
         i=LastExchange;
      }//while
} 



三:选择排序:
void   SelectSort(RecType R[],int n)
{ //对记录序列R[1..n]作直接选择排序。
  for(i=1; i<n; i++) //选择第i小的记录,并交换到位
      {k=i;  //设无序序列第1个元素的关键字最小  
       for(j=i+1;j<=n;j++) //找最小元素的下标
           if(R[j].key<R[k].key)  
                k=j;                //记当前最小元素的下标
       if(i != k)  
           R[i]←→R[k];     //与无序序列第1个记录交换
      }//for
}//SelectSort




四:快速排序:
int  Partition(RecType R[ ],int l,int h)
{ //交换记录子序列R[l..h]中的记录,使枢轴记录到位并返回其所在位置
  int i=l; j=h;   //用变量i,j记录待排序记录首尾位置
  R[0] = R[i]; //以子表的第一个记录作枢轴,将其暂存到记录R[0]中
  x = R[i].key;   //用变量x存放枢轴记录的关键字
  while(i<j) //从表的两端交替地向中间扫描
      { while(i<j && R[j].key>=x)  j--;
        R[i] = R[j];    //将比枢轴小的记录移到低端(不交换)
        while(i<j && R[i].key<=x)  i++;
        R[j] = R[i];    //将比枢轴大的记录移到高端(不交换)
       }//while
 R[i] = R[0];        //枢轴记录到位
 return i;            //返回枢轴位置
}//Partition


void QuickSort(RecType R[ ],int s,int t)
 {//对记录序列R[s..t]进行快速排序
  if(s<t)
      { k=Partition(R,s,t);
        QuickSort(R,s,k-1);
        QuickSort(R,k+1,t);
       }//if
  }//QuickSort
  



性能分析:  
平均时间复杂度为O(nlog2n)
                    最差为O(n2)


五:归并排序
void    Msort(RecType R[ ],RecType R1[ ],int s,int t)
{   //将R[s..t]进行2-路归并排序为R1[s..t]
  if(s==t)  
      R1[s]=R[s];
  else
     {m=(s+t)/2;                //将R[s..t]平分为R[s..m]和R[m+1..t]
      Msort(R,R1,s,m);     //递归地将R[s..m]归并为有序的R1[s..m]
      Msort(R,R1,m+1,t); //递归地R[m+1..t]归并为有序的R1[m+1..t]
      Merge(R1,R,s,m,t); //将R1[s..m]和R1[m+1..t]归并到R[s..t]
     }//if
}//MSort


void   MergeSort(RecType R[],int n)
{ //对记录序列R[1..n]作2-路归并排序。
   MSort(R,R1,1,n);
}//MergeSort




性能分析:
归并排序的设计复杂度为O(nlogn)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值