• 排序


    各种排序方法的综合比较


    结论:
       排序方法 平均时间 最坏时间 辅助存储
       简单排序 O(n2)  O(n2)  O(1)
       快速排序 O(nlogn) O(n2)         O(logn)
       堆排序 O(nlogn) O(nlogn) O(1)
       归并排序 O(nlogn) O(nlogn) O(n)
       基数排序 O(d(n+rd)) O(d(n+rd)) O(rd)
    另外:直接插入排序、冒泡排序为简单排序,希尔排序(不稳定)

    一、时间性能 

    按平均的时间性能来分,有三类排序方法:
    时间复杂度为O(nlogn)的方法有:快速排序、堆排序和归并排序,其中以快速排序为最

    好;

    时间复杂度为O(n2)的有:直接插入排序、起泡排序和简单选择排序,其中以直接插入为

    最好,特别是对那些对关键字近似有序的记录序列尤为如此;

    时间复杂度为O(n)的排序方法只有,基数排序。

    当待排记录序列按关键字顺序有序时,直接插入排序和起泡排序能达到O(n)的时间复杂

    度;而对于快速排序而言,这是最不好的情况,此时的时间性能蜕化为O(n2),因此是应

    该尽量避免的情况。
    简单选择排序、堆排序和归并排序的时间性能不随记录序列中关键字的分布而改变。
    二、空间性能

    指的是排序过程中所需的辅助空间大小。

    1. 所有的简单排序方法(包括:直接插入、起泡和简单选择)和堆排序的空间复杂度为O

    (1);

    2. 快速排序为O(logn  ),为栈所需的辅助空间;

    3. 归并排序所需辅助空间最多,其空间复杂度为O(n );

    4.链式基数排序需附设队列首尾指针,则空间复杂度为O(rd  )。

    三、排序方法的稳定性能

    1. 稳定的排序方法指的是,对于两个关键字相等的记录,它们在序列中的相对位置,在

    排序之前和经过排序之后,没有改变。

    2. 当对多关键字的记录序列进行LSD方法排序时,必须采用稳定的排序方法。

    3. 对于不稳定的排序方法,只要能举出一个实例说明即可。

    4. 快速排序和堆排序是不稳定的排序方法

    #include <stdio.h>
    #include <stdlib.h>

    void ss_sort(int e[],int n)
    {
      int i,j,k,t;
      for (i=0;i<n-1;i++) {
        for (k=i,j=i+1;j<n;j++)
          if (e[k]>e[j]) k=j;
        if (k!=i) {
          t=e[i]; e[i]=e[k]; e[k]=t;
        }      
      }     
    }    

    void si_sort(int e[],int n)
    {
      int i,j,t;
      for (i=1;i<n;i++)
      {
        for (t=e[i],j=i-1;j>=0 && t<e[j];j--)
          e[j+1]=e[j];
        e[j+1]=t;   
      }      
    }

    void sb_sort(int e[],int n)
    {
      int j,p,h,t;
      for (h=n-1;h>0;h=p)
      {
        for (p=j=0;j<h;j++)
        if (e[j]>e[j+1]) {
          t=e[j];
          e[j]=e[j+1];
          e[j+1]=t;
          p=j; 
        }    
      }      
    }    

    void shell(int e[],int n)
    {
      int j,k,h,y;
      for (h=n/2;h>0;h=h/2)
        for (j=h;j<n;j++) {
          y=e[j];
          for (k=j-h;k>=0&&y<e[k];k-=h)
            e[k+h]=e[k];
          e[k+h]=y;   
        }      
    }    

    void sift(int e[],int n,int s)
    {
      int t,k,j;
      t=e[s];
      k=s; j=2*k+1;
      while (j<n) {
        if (j<n-1&&e[j]<e[j+1])
           j++;
        if (t<e[j]) {
          e[k]=e[j];
          k=j;
          j=2*k+1;
        }
        else
          break;        
      }       
      e[k]=t;
    }    

    void heapsort(int e[],int n)
    {
      int i,k,t;
      for (i=n/2-1;i>=0;i--)
        sift(e,n,i);
      for (k=n-1;k>=1;k--) {
        t=e[0];
        e[0]=e[k];
        e[k]=t;
        sift(e,k,0); 
      }         
    }    

    void r_quick(int e[],int low,int high)
    {
      int i,j,t;
      if (low<high) {
        i=low;  j=high; t=e[low];
        while (i<j) {
          while (i<j && e[j]>t) j--;
          if (i<j) e[i++]=e[j];
          while (i<j && e[i]<=t)i++;
          if (i<j) e[j--]=e[i];     
        }      
        e[i]=t;
        r_quick(e,low,i-1);
        r_quick(e,i+1,high);
      } 

    void merge_step(int e[],int a[],int s,int m,int n)  
    {
      int i,j,k;
      k=i=s;  j=m+1;
      while (i<=m && j<=n)
        if (e[i]<=e[j]) a[k++]=e[i++];
        else a[k++]=e[j++];
      while (i<=m) a[k++]=e[i++];
      while (j<=n) a[k++]=e[j++];      
    }    

    void merge_pass(int e[],int a[],int n,int len)
    {
      int f_s,s_end;
      f_s=0;
      while (f_s+len<n) {
        s_end=f_s+2*len-1;
        if (s_end>=n) s_end=n-1;
        merge_step(e,a,f_s,f_s+len-1,s_end);
        f_s=s_end+1;   
      }         
      if (f_s<n)
        for (;f_s<n;f_s++)
          a[f_s]=e[f_s];
    }  

    void merge(int e[],int n)
    {
      int *p=(int *)malloc(sizeof(int)*n);
      int len=1,f=0;
      while (len<n) {
        if (f==0) merge_pass(e,p,n,len);
        else merge_pass(p,e,n,len);
        len *=2;
        f=1-f;   
      }      
      if (f)
        for (f=0;f<n;f++) e[f]=p[f];
      free(p);   
    }      

    int main(int argc, char *argv[])
    {
      int a[8]={4,6,2,1,3,9,10,5},*p,i=0; 
     
      ss_sort(a,8);
      for (p=a;p<a+8;p++)
        printf("%d\n",*p);
      printf("\n"); 
       
      si_sort(a,8);
      for (p=a;p<a+8;p++)
        printf("%d\n",*p);
      printf("\n");  
     
      sb_sort(a,8);
      for (p=a;p<a+8;p++)
        printf("%d\n",*p);
      printf("\n");   
     
      shell(a,8);
      for (p=a;p<a+8;p++)
        printf("%d\n",*p);
      printf("\n");  
     
      heapsort(a,8);
      for (p=a;p<a+8;p++)
        printf("%d\n",*p);
      printf("\n"); 
     
      r_quick(a,0,7);
      for (p=a;p<a+8;p++)
        printf("%d\n",*p);
      printf("\n"); 
     
      merge(a,8);
      for (p=a;p<a+8;p++)
        printf("%d\n",*p);
      printf("\n"); 
      system("PAUSE"); 
      return 0;
    }

  • 相关阅读:
    C#|.NET从控制反转(依赖注入)想到事件注入 (非AOP)
    libevent 2.1.3 for VS2008 source code
    如何进行object以及Array(数组)的深复制
    Flash ProgressEvent.bytesTotal为0的原因和解决
    Flash字体嵌入方法总结—(4)进阶篇
    mysql分组取每组前几条记录(排名) 附group by与order by的研究
    Flash游戏优化技巧
    教程:深入理解Flash的沙箱 – Application Domains
    Flash Player 11异步解码Bitmap
    常用公式
  • 原文地址:https://www.cnblogs.com/djcsch2001/p/2035156.html
Copyright © 2020-2023  润新知