各种排序算法总结

最简单的排序:

      冒泡排序:

               一种交换排序,算法的思想是:两两交换相邻记录的关键字,如果反序则交换,直到不存在反序的记录为止

              

void  sort(int *a ,int  num)
{
     if(a==NULL||num<1)
           return ;
     int i,j;
     for(i=0;i<num-1;i++)
       for(j=num-1;j>i;j--)
            if(a[j]<a[j-1])
               swap(a+j,a+j-1);
}
       冒泡排序的优化:

              试想一种情况,当一个数列是这样子的:{2,1,3,4,5,6,7,8,9},经过一次冒泡排序之后会变成这样子:{1,2,3,4,5,6,7,8,9},如此可见,下面已经没有比较的必要了,所以这里存在着一种优化的可能,我们需要一个标志位,来记录是否在排序过程中发生过交换,如果未发生交换,则证明已经有序,则不需要再进行交换。

        

void  sort2(int* a,int num)
{
      if(a==NULL||num<1)
          return ;
      bool  flag=true;
      int i,j;
      for(i=0;i<num-1&&flag;i++)
        {
            flag=false;
            for(j=num-1;j>i;j--)
                if(a[j]>a[j-1])
                  {
                       flag=true;
                       swap(a+j,a+j-1);
                  }
}

}

简单选择排序:

          简单选择排序是指:假设0到i已经有序,在剩下的元素中选择最小的元素与第I+1位置上的元素进行交换

         

void   sort(int* a,int num)
{
     if(a==NULL||num<=0)
           return ;
     int i,k,minindex;
      for(i=0;i<num-1;i++)
      {
            minindex=i;
            for(k=i+1;k<num;k++)
                if(a[minindex]<a[k])
                    k=minindex;
            if(minindex!=i)
               swap(a+i,a+minindex);
        }
}
直接插入排序: 直接插入排序不是选择在待排序的元素中选择最小值,而是将待排序的元素放入已经排序的数组中的正确的位置

 

void insertsort(int *a ,int num)
{
     if(a==NULL||num<=0)
            return ;
     int  i,j,temp;
     for(i=1;i<num;i++)
     {
           temp=a[i];
           for(j=i;j>0;j--)
              {
                 if(a[j-1]>temp)
                     a[j]=a[j-1];
                 else
                      break;
              }
           a[j]=temp;
       }
}
希尔排序:这个排序就是定义一个间距 distance,将每隔distance间距的子数组当成一个小数组,对其进行直接插入排序,然后将间距逐渐的减小,对于每个减小的间距使用上述同样的方法,直到最后的间距为1,这个时候就是直接插入排序,

void  shellsort(int *a,int num)
{
        if(a==NULL||num<=0)
               return ;
         int  distance=num;
         int  i,j,temp;
         do{
             distance=distance/3+1;
             for(i=distance;i<num;i++)
             {
                 if(a[i-distance]>a[i])
                  {
                     temp=a[i];
                     for(j=i;j>0;j-=distance)
                         {
                                if(a[j-distance]>temp)
                                       a[j]=a[j-distance];
                                else
                                        break;
                         }
                       a[j]=temp;
                   }
              }
         }while(distance>1);
}           




堆排序:堆排序是利用完全二叉树进行排序,同时这种完全二叉树有种特性,(因为我们是按照从小到大进行排序的)既是:所有的父节点的值都小于子节点的值(如果子节点存在的话),这样不难看出最小的值一定是在根节点,我们利用这个性质可以进行排序
       堆排序中存在着两个重要的过程,就是上虑和下虑的过程,前者用来当Heap(1,n-1)时建立Heap(1,n),后者用来当删除堆顶元素时重新建立堆的过程,

      下面是代码片段:

       注意:这里的下标都是从1开始的,这样在求子节点的时候很好计算

    

void  siftdown(int *a,int i,int num)
{
     int child;
     int temp=a[i];
     int j;
     for(j=i;j*2<=num;)
     {
        child=2*j;
        if(child+1<=num&&a[child+1]<a[child])
           child++;
        if(a[child]<temp)
        {
           a[j]=a[child];
           j=child;
         }
         else
           break;
      }
      a[j]=temp;
}
void  siftup(int* a,int num)
{
    int temp=a[num];
    int i=num;
    for(;1<=i/2;)
    {
      if(temp<a[i/2])
       {
         a[i]=a[i/2];
         i>>1;
        }
       else
          break;
    }
    a[i]=temp;
}
        
上面的是上虑和下虑的过程,

下面是建堆和进行堆排序的过程

void  BuildHeap(int*a,int num)
{
    int i;
    for(i=2;i<=num;i++)
        siftup(a,i);//调用上虑进行建队
}
void  HeapSort(int *a,int num)
{
   BuildHeap(a,num);
   int i=num;
   while(i>=1)
   {
      printf("%d ",a[1]);
      a[1]=a[i];
      i--;
      if(i>=1)
        siftdown(a,1,i);//调整进行重新建队
      else
         break;
   }
 }
     
归排和快排明天再说

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值