“漂亮的”排序算法 Stooge Sort 如何完成排序

  Stooge Sort 是一种低效的递归排序算法,甚至慢于冒泡排序。在《算法导论》第二版第7章(快速排序)的思考题中被提到,是由Howard、Fine等教授提出的所谓“漂亮的”排序算法。

  相比经典排序来讲,Stooge Sort 并不是一种优秀的排序算法,但是它的代码十分“漂亮”。简短地几行代码便可完成排序功能。

algorithm stoogesort(array L, i = 0, j = length(L)-1)       

     if L[j] < L[i] then 

         L[i] ↔ L[j] 

     if (j - i + 1) >= 3 then 

         t = (j - i + 1) / 3 

         stoogesort(L, i  , j-t) 

         stoogesort(L, i+t, j  ) 

         stoogesort(L, i  , j-t) 

     return L 

基本理论

  • 如果最后一个值小于第一个值,则交换它们
  • 如果当前子集元素数量大于等于3:
    1. 使用臭皮匠排序前2/3的元素
    2. 使用臭皮匠排序后2/3的元素
    3. 再次使用臭皮匠排序前2/3的元素 
算法分析

 
  • 池的划分
    Stooge Sort 把待排序数组分成三个部分:A.小值池、B.交换池、C.大值池。因为数组元素数量可能不被 3 整除,所以这三个池大小大致各占三分之一,但是必须保证 B.交换池 的大小要大于等于其他两个池。
  • 池的排序
    划分池后,Stooge Sort 算法整体可以描述为:
    1. 排序 AB 池元素
    2. 排序 BC 池元素
    3. 排序 AB 池元素
  • 微观排序(3 个元素)
    如果排序元素只有 3 个,那么这 3 个元素会分别占有一个池。根据算法理论,
    1. Stooge Sort 会先对 AB 池排序,较大的元素会进入 B.交换池;
    2. 然后对 BC 池排序,较大的元素会进入 C.大值池;
    3. 最后再次对 AB 池排序,较小值会进入 A.小值池,较大值会进入 B 池。
    排序结果:最小值进入 A.小值池,最大值进入 C.大值池。完成排序。
  • 宏观排序(多于 3 个元素)
    如果排序元素多于 3 个,那么就会涉及到池的划分。池的划分必须满足 B.交换池 的大小要大于等于其他两个池,试想,如果 B.交换池 小于其他两个池,那么第 2 步将不能保证所有大值进入 C.大值池;同样第 3 步也不能保证所有小值进入 A.小值池。
    划分池后,对一个大数组的排序便可以分治成对若干个小数组的排序,直到排序元素数量为 3。
优化的 Stooge Sort

  下面是我对 Stooge Sort 优化后的 C 语言代码:

void stooge(int a[],int i ,int j)
{
    if (j-i+1 >= 3)
    {
        int t=(j-i+1)/3;
        stooge(a, i, j-t);
        stooge(a, i+t, j);
        stooge(a, i, j-t);
    }
    else if (a[i] > a[j])
    {
        int tmp;
        tmp=a[i]; a[i]=a[j]; a[j]=tmp; 
    }
}

 

原创信息
作者:唯梦永恒
发表日期:2014-5-6
版权说明:自由复制,保留署名
posted @ 2014-05-06 17:28  唯梦永恒  阅读(1979)  评论(0编辑  收藏  举报