算法导论-7-2 针对有相同元素值的快速排序

     题目详见算法导论7-2习题,在这里我就不再赘述。

     本文分为三个部分,第一部分是写我改进算法的思路,第二部分是算法实现,第三部分是程序运行结果。

     思路

    《算法导论》里介绍的partition没有考虑元素相等的情况,但是就算存在相同元素快排其实也可以适用的,只是相等的元素当作大于key的元素处理了。习题7-2要求经过partition函数之后与数组变为三个部分,最左边的是小于key(就是原算法里的a[r]),中间部分等于key,最右边大于key。联想到原来的partition函数采用一个变量i来记录小于key的元素的个数,我想可不可以也采用一个变量t来记录小于等于key的元素个数,其中i+1到t是等于key的元素。因此,当出现小于或者等于key的元素t加一,i也要加一。然后按照原来的思想exchange(a[t],a[j])。但是又到了解决问题的关键,只是这样交换一次还不能达到我们的目的,我们必须注意到这个现象从p到i是小于key的元素,从i+1到t是等于key的元素,我们经过exchange(a[t+1],a[j])之后a[t+1]是一个小于等于key的元素,若其小于key我们需要exchange(a[t],a[i]),将小于key的元素交换到最左边,这样我们就成功的将数组里元素分为三部分。

    算法实现


int *partition(int *a,int p,int r)
{
    int key=a[r];
    int i=p-1;
    int t=p-1;
    int j,temp;
    for(j=p;j<r;j++)
    {
      if(a[j]<key)   //比key小就放在左边 
      {
       i++;
       t++;
       temp=a[t];
       a[t]=a[j];
       a[j]=temp;      
       if(i<t)
       {        
       temp=a[t];   //与key一样大小的swap 
       a[t]=a[i];
       a[i]=temp;
       }
      }
      else if(a[j]==key)
      {
           t++;
           temp=a[t];
           a[t]=a[j];
           a[j]=temp;
      }
    }
    temp=a[r];      // i+1到t+1等于key 
    a[r]=a[t+1];
    a[t+1]=temp;
    int *po=(int *)malloc(sizeof(int)*2);   //存储返回值
    *po=i+1;
    *(po+1)=t+1;
    return po; 
}
void quicksort(int *a,int p,int r)
{
     int *po;
     if(p<r)
     {
            po=partition(a,p,r);
            quicksort(a,p,*po-1);
            quicksort(a,*(po+1)+1,r);
     }
}

    原文作者:排序算法
    原文地址: https://blog.csdn.net/u013252593/article/details/23667387
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞