近日,学习了几种排序算法,做一梳理:

一、插入排序

插入排序的主要思想就是在放置第P个位置的值时认为前P-1个位置的值是按正确位置排序好的,
所以将P逐一与它之前位置的值比较后放置在合适的位置。主要算法:

void InsertionSort(int A[],int N)
{
   int j,p;
   int temp;

   for(p=1;p<N;p++)
   {
      temp=A[p];
      for(j=p;j>0&&A[j-1]>temp;j--)
      {
         A[j]=A[j-1];
      }
      A[j]=temp;
   } 
}


二、希尔排序

它的主要思想是通过比较相距一定间隔的元素来工作;各趟比较所用的距离随着算法的进行减少,直到只比较相邻元素的最后一趟

排序为止。主要算法:

void ShellSort(int A[],int N)
{
  int j,p;
  int increase;
  int temp;

  for(increase=N/2;increase>0;increase/=2)
  {
     for(p=increase;p<N;p++)
     {
        temp=A[p];
        for(j=p;j>=increase;j-=increase)
         {
              if(A[j-increase]>temp)
                 A[j]=A[j-increase];
              else
                 break;
          }
          A[j]=temp;
     }  
  }
}

三、堆排序

它的主要思想是构建一个二叉堆,然后每次通过Delete操作得到一个最大值。主要算法:

#define LeftChild(i) (2*(i)+1)

void PercDown(int A[],int i,int N)
{
     int child;
     int temp;
    
     for(temp=A[i];LeftChild(i)<N;i=child)
     {
         child=LeftChild(i);
         if(child!=N-1&&A[child+1]>A[child])
              child++;
         if(temp<A[child])
               A[i]=A[child];
         else
               break;
      }
      A[i]=temp;
}

void Swap(int *a,int *b)
{
    int t=*a;
    *a=*b;
    *b=t;
}

void HeapSort(int A[],int N)
{
   int i;
  
   for(i=N/2;i>=0;i--)
     PercDown(A,i,N);
   for(i=N-1;i>=0;i--)
   {
     Swap(&A[0],&A[i]);
     PercDown(A,0,i);
   }
}

四、归并排序

它的主要思想是合并两个已排序的表。主要算法:

/*Lpos=start of the left half,Rpos=start of right half */
void Merge(int A[],int TmpArray[],int Lpos,int Rpos,int RightEnd)
{
    int i,LeftEnd,numElements,TmpPos;

    LeftEnd=Rpos-1;
    TmpPos=Lpos;
    numElements=RightEnd-Lpos+1;

    while(Lpos<=LeftEnd&&Rpos<=RightEnd)
    {
        if(A[Lpos]<=A[Rpos])
          TmpArray[TmpPos++]=A[Lpos++];
        else
          TmpArray[TmpPos++]=A[Rpos++];
    }

    while(Lpos<=LeftEnd) /*Copy rest of first half */
       TmpArray[TmpPos++]=A[Lpos++];
    while(Rpos<=RightEnd) /*Copy rest of second half */
       TmpArray[TmpPos++]=A[Rpos++];

    for(i=0;i<numElements;i++,RightEnd--)
       A[RightEnd]=TmpArray[RightEnd];  //Not always definite from zero
}

void MSort(int A[],int TmpArray[],int Left,int Right)
{
    int Center;

    if(Left<Right)
    {
        Center=(Left+Right)/2;
        MSort(A,TmpArray,Left,Center);
        MSort(A,TmpArray,Center+1,Right);
        Merge(A,TmpArray,Left,Center+1,Right);
    }
}

void MergeSort(int A[],int N)
{
    int *TmpArray;

    TmpArray=malloc(N*sizeof(int));
    if(TmpArray!=NULL)
    {
        MSort(A,TmpArray,0,N-1);
        free(TmpArray);
    }
    else
        exit(EXIT_FAILURE);
}

五、快速排序

它的主要思想是:
1、如果S中元素个数是0或1,则返回。
2、取S中任一元素v,称为pivot.
3、将S分为两个不相交的集合:S1和S2
4、返回{quicksort(S1)后,继随v,继而quicksort(S2)}

主要算法:

#define Cutoff(3)

int Median3(int A[],int Left,int Right)
{
    int Center=(Left+Right)/2;

    if(A[Left]>A[Center])
       Swap(&A[Left],&A[Center]);
    if(A[Left]>A[Right])
       Swap(&A[Left],&A[Right]);
    if(A[Center]>A[Right])
       Swap(&A[Center],&A[Right]);

    Swap(&A[Center],&A[Right-1]);
    return A[Right-1];
}

void Qsort(int A[],int Left,int Right)
{
    int i,j;
    int pivot;

    if(Left+Cutoff<=Right)
    {
       pivot=Median3(A,Left,Right);
       i=Left;j=Right-1;

       for(;;)
       {
          while(A[++i]<pivot){}
          while(A[--j]>pivot){}

          if(i<j)
            Swap(&A[i],&A[j]);
          else
             break;
        }
        Swap(&A[i],&A[Right-1]);

        Qsort(A,Left,i-1);
        Qsort(A,i+1,Right);
     }
     else
       InsertionSort(A+Left,Right-Left+1);
}

void QuickSort(int A[],int N)
{
    Qsort(A,0,N-1);
}

posted on 2011-07-02 20:30  liveshow021  阅读(145)  评论(0编辑  收藏  举报