zoukankan      html  css  js  c++  java
  • 常用排序算法(转)

    1.插入排序

    由N-1趟排序组成,对于p=1到p=N-1趟,插入排序保证从位置0到位置p上的元素为已排序状态。

    时间复杂度:O(N^2)

    代码
    void InsertionSort(ElementType A[],int N)
    {
      
    int j,p;
      ElementType Tmp;
      
    for(p=1;p<N;p++)
      {
        Tmp
    =A[j];//把A[j]保存下来,因为它要被插入到前面的某个位置去
        for(j=p;j>0&&A[j-1]>Tmp;j--)//大于A[j]的元素逐个后移
         {
           A[j]
    =A[j-1];
         }
        A[j]
    =Tmp;
      }
    }

    2.希尔排序

    希尔排序使用一个序列h1,h2,h3,ht,叫做增量排序。在使用增量hk的一趟排序之后,对于每个i我们有A[i]<A[i+hk],所有相隔hk的元素被排序。

    时间复杂度:O(N^(1+a)),其中0<a<1。

    代码
    //代码不太好理解,使用了3层循环
    void ShellSort(ElementType A[],int N)
    {
        
    int j,p,Increment;
        ElementType Tmp;
        
    for(Increment=N/2;Increment>0;Increment/=2)
        {
            
    for(p=Increment;p<N;p++)
            {
                Tmp
    =A[p];
                
    for(j=p;j>=Increment;j-=Increment)
                {
                    
    if(A[j]<A[j-Increment])
                        A[j]
    =A[j-Increment];
                    
    else
                        
    break;
                }
                A[j]
    =Tmp;
            }
        }
    }

    3. 堆排序

    思想:建立小顶堆,然后执行N次deleteMin操作。

    时间复杂度:O(NlogN),实践中,慢于sedgewick的希尔排序

    空间复杂度:O(N),用于建立堆得数组

    4.归并排序

    使用递归把数组分为两部分分别排序,然后合并成一个数组

    时间复杂度:O(NlogN)

    空间复杂度:O(N)

    代码
    void Merge(ElementType A[],ElementType 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)
            TmpArray[TmpPos
    ++]=(A[Lpos]<A[Rpos])?A[Lpos++]:A[Rpos++];
        
    while(Lpos<LeftEnd)
            TmpArray[TmpPos
    ++]=A[Lpos++];
        
    while(Rpos<RightEnd)
            TmpArray[TmpPos
    ++]=A[Rpos++];

        
    for(i=0;i<NumElements;i++,RightEnd--)
            A[RightEnd]
    =TmpArray[RightEnd];
    }

     5.快速排序

    对于小数组(N<20),快排不如插排好。一种好的截止范围是N=10,大于10则用快排。

    快排的四步:

    ①如果S中元素个数是0或1,则返回

    ②取S中间元素v为枢纽元

    ③将S-{v}分成两个不相交的集合:分别是S1(小于v),和大于v的部分S2

    ④返回quicksort(S1),继随v,继而quicksort(S2)

    时间复杂度:O(NlogN)

    编程思想:1.选取枢纽元,取首尾及中间的三个元素,排序,小的排在首位,大的排在尾部,中的作为枢纽元

    2.排序时把枢纽元放在Right-1的位置上,i=Left+1;j=Right-2;开始交换过程

    代码
    ElementType Median3(ElementType 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];
    }

    Qsort(ElementType A[],
    int Left,int Right)
    {
        
    int i,j;
        ElementType Pivot;
        
    if(Left+9<Right)    //10个元素以上的数组使用快排
        {
            Pivot
    =Median3(A[],Left,Right);
            i
    =Left+1;
            j
    =Right-2;
            while(1)
            {
            
    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
            InsertSort(A,Right
    -Left+1);
    }

     6.直接选择排序

    描述:选出数组中最小的元素,与数组的第一个元素交换;然后选择出数组中次小的元素,与与第二个元素交换,直到完成

    选择排序需要比较N(N-1)/2次,即N2次,而交换则只需要N-1

    对于是否已经排好序,或者随机文件,所花费的时间是一致的,即执行时间具有强迫性

    选择排序应用在数据项比较大,键比较小的情况下,因为此时移动元素花费时间较多,而对于其他排序算法,元素移动频繁的多

    代码
    void sort(ElementType A[], int N) 

      
    int i, j; 
      
    int min; 
      
    for(i=0; i<N-1; i++
      { 
        min 
    = i; 
        
    for(j=i+1; j<=N-1; j++
        
    if(A[j]<A[min]) min=j; 
          swap(A[i],A[min]); 
      }    

  • 相关阅读:
    android 多线程
    Uva 10881 Piotr’s Ants 蚂蚁
    LA 3708 Graveyard 墓地雕塑 NEERC 2006
    UVa 11300 Spreading the Wealth 分金币
    UVa 11729 Commando War 突击战
    UVa 11292 The Dragon of Loowater 勇者斗恶龙
    HDU 4162 Shape Number
    HDU 1869 六度分离
    HDU 1041 Computer Transformation
    利用可变参数函数清空多个数组
  • 原文地址:https://www.cnblogs.com/buffer/p/1619258.html
Copyright © 2011-2022 走看看