zoukankan      html  css  js  c++  java
  • 不用辅助空间的归并排序

     

    题目要求:合并两个已有序序列为A[0…i],A[i+1…N-1] 为A[0...N-1], 要求不用或者只使用常量辅助空间

    为叙述方便,表示A[0…i]为a[0..n-1],A[i+1…N-1]为b[0…m-1],问题实际上是使用常数辅助空间的归并排序

     

    不用辅助空间的归并排序

    思路如下:如果a[0] 小于b[0],问题变为合并a[1..n-1]和b[0…m-1],还是同一个问题迭代解决

    否则,即a[0]大于b[0],交换两个元素,此时b[0]可能大于b[1], 用冒泡排序的方法将b[0]向右移动合适的位置,接下来问题也变为合并a[1..n-1]和b[0…m-1],迭代解决。

    复杂度分析:考虑一种极端情况,前半部分的元素全部大于后半部分,即a中的所有元素都大于b中的元素,这时以第一个元素为例,比较次数为1+(m-1)=m, m-1次为冒泡移动的比较次数,所以合并的复杂度为m+(m-1)+(m-2)+..=1= m*(m+1)/2,在此说明,这时一种极端情况。当前部分元素完全小于后部分是,则元素比较次数为n。如果一个完整的归并排序使用这种方法,则最坏复杂度为T(n)=2T(n/2)+ (n/2)*(n/2 +1)=2T(n/2) + n(n+1)/4,取极限为n(n+1)/2,即此时归并排序的复杂度和冒泡排序已经一样,从这一点来看和快排还是很相似的。

     

    使用k个辅助空间的归并排序,k远远小于元素数目,辅助数组为c[k]

    原理类似,将a[0…k-1]移到c[0…k-1]中,然后用常规方法将b[0..m-1]和c[0…k-1]归并k个元素到位置a[0…k-1],比较次数为k,假设此时数组c中剩余的元素为c[t…k-1],则此时数组b中前端必然也空出了k—t个位置,即b[0..k-t-1]必然没有元素。接下将b[k-t…m-1]和c[t…k-1]归并到b中的前端空位,比较次数最多为m, 数组c变为空,现在问题变成了归并a[k…n-1] 和b[0…m-1]了,迭代解决,注意终止条件。

    复杂度分析:每次迭代的最多比较次数为将k+m,一共有n/k次迭代,所以总复杂度为(k+m)*(n/k)=n+(nm)/k,当k=n时即是原来的归并排序复杂度(nlogn),当k=1时即为不用辅助空间的排序复杂度n^2。

    再次说明,上述的n^2复杂度都是基于初始序列完全逆序的极端情况,个人认为,平均情况下使用辅助空间的渐进复杂度复杂度应该也是对数级。

  • 相关阅读:
    inline, block, and inline-block
    分布式/集群/负载均衡的基本概念与区别
    Java获取当前进程的所有线程
    关于测试Windows电脑端口的命令 —— telnet用法
    关于 ArtifactTransferException: Failure to transfer
    Maven项目报错:The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path
    Java去除掉HTML里面所有标签的两种方法——开源jar包和自己写正则表达式
    SQL(基于MySQL)——LIMIT用法
    毕业设计进度:2月13日
    毕业设计进度:2月12日
  • 原文地址:https://www.cnblogs.com/gaoyanqing/p/4310800.html
Copyright © 2011-2022 走看看