zoukankan      html  css  js  c++  java
  • 串行的BitonicSort双调排序

         最近由于需要在GPU上做排序,因为GPU的并行性,所以需要一个并行的排序算法。而BitonicSort双调排序是一个非常适合并行化的排序算法,其在《算法导论》的排序网络一章对其基本原理做了描述与证明。有兴趣大家可以看看。

        作为个人的一个学习总结,这里只是对其性质做些简单介绍,以及它算法基本思想和几个重要的步骤。如果需要了解BitonicSort更加详细的理论证明,可以参考《算法导论》。

        首先BitonicSort的算法复杂度为O(n(logn)^2),看到这里大家会问比快排O(nlogn)要慢啊,干嘛要用它?但是它的n在并行机(比如GPU)上可以并行化掉n,那么复杂度就变为O( (logn)^2 )了,自然比快排等要快。

        下面说下它算法思想和为什么它适合并行化。

        BitonicSort主要算法思想:以有n个元素的0-1数组array递增排序为例。

        第一步:先数组划分成两半,一半是Bitonic递增序列,一半是Bitonic递减序列。Bitonic递增序列可以理解为可以先递增,后递减(也可以只递增),比如:0001110000001111;反之Bitonic递减序列形如111100001111111111111111110000000000000

        第二步:将元素array[i](0<=i<n/2)array[i+n/2]比较

            If(array[i]>array[i+n/2])

              Exchange(array[i],array[i+n/2]);

        然后大家可以简单地证明:数组最小的n/2个元素在前面一半,最大n/2个元素在后面一半。继而不断递归便可得到有序数组。从上面可以看到BitonicSort也存在一个致命的缺点,因为不断的二分,所以原始的BitonicSort只能够排序2^n长度的数组,如何改进下一次再补充。

        为了突出关键,这里只贴出关键部分的代码,其中主要调用SortUp(int beg,int n)这个函数,按照递增排序数组从beg开始的n个元素

    int main()

    {

    BitonicSort biSort;

    int n=1<<15;

    biSort.InitRandData(n);

    biSort.SortUp(0,n);

    cout<<"The Sorted Result is:"<<endl;

    biSort.OutputArray();

    }


    void BitonicSort::SortUp(int beg,int n)

    {

    if(n==1)return;

    SortUp(beg,n/2);//把前面的n/2个元素按递增排序

    SortDown(beg+n/2,n/2);//把后面n/2个元素按递减排序

    MergeUp(beg,n);//合并前面n/2个和后面n/2个数组。

    return;

    }


    void BitonicSort::SortDown(int beg,int n)//类似SortUp,只是按照递减排序数组从beg开始的n个元素

    {

    if(n==1)return;

    SortUp(beg,n/2);

    SortDown(beg+n/2,n/2);

    MergeDown(beg,n);

    }


    void BitonicSort::MergeUp(int beg,int n)

    {

    if(n==1)return;

    int halfN=n>>1;

    for(int i=beg;i<beg+halfN;i++)

    {

    if(array[i]>array[i+halfN])Exchange(array[i],array[i+halfN]);

    }

    MergeUp(beg,halfN);

    MergeUp(beg+halfN,halfN);

    return;

    }

    void BitonicSort::MergeDown(int beg,int n)

    {

    if(n==1)return;

    int halfN=n>>1;

    for(int i=beg;i<beg+halfN;i++)

    {

    if(array[i]<array[i+halfN])Exchange(array[i],array[i+halfN]);

    }

    MergeDown(beg,halfN);

    MergeDown(beg+halfN,halfN);

    return;

    }


  • 相关阅读:
    作业帮:最长连续序列(头部插入)
    作业帮:字符串反转(头部插入)
    作业帮:给定一个整数数组,找出其中两个数相加等于目标值(去重set)
    JVM系列之七:HotSpot 虚拟机
    JVM系列之六:内存溢出、内存泄漏 和 栈溢出
    JVM系列之四:运行时数据区
    JVM系列之五:垃圾回收
    JVM系列之三:类装载器子系统
    JVM系列之二:编译过程
    JVM系列之一:JVM架构
  • 原文地址:https://www.cnblogs.com/bester/p/3255783.html
Copyright © 2011-2022 走看看