Java 这是快速排序的正确实现吗?

Java 这是快速排序的正确实现吗?,java,quicksort,Java,Quicksort,我想检查一下这是否是一个正确的QuickSort实现,它似乎在做这项工作,但我是否遗漏了什么 public class QuickSort implements Sorter { public void sort(Comparable[] items) { QuickSort(items, 0, items.length - 1); } static void QuickSort(Comparable[] items, int a, int b) { int lo = a;

我想检查一下这是否是一个正确的QuickSort实现,它似乎在做这项工作,但我是否遗漏了什么

public class QuickSort implements Sorter {

public void sort(Comparable[] items) {
    QuickSort(items, 0, items.length - 1);
}

static void QuickSort(Comparable[] items, int a, int b) {
    int lo = a;
    int hi = b;
    if (lo >= hi) {
        return;
    }
    Comparable mid = items[(lo + hi) / 2];
    Comparable T;

    while (lo < hi) {
        while (items[lo].compareTo(mid)<0) {
            lo++;
        }
        while (mid.compareTo(items[hi])<0) {
            hi--;
        }
        if (lo < hi) {
            T = items[lo];
            items[lo] = items[hi];
            items[hi] = T;
        }
    }

    QuickSort(items, a, lo);
    QuickSort(items, lo == a ? lo + 1 : lo, b);

}
公共类快速排序实现分类器{
公共作废排序(可比[]项){
快速排序(items,0,items.length-1);
}
静态void快速排序(可比[]项,int a,int b){
int-lo=a;
inthi=b;
如果(低>=高){
返回;
}
可比中期=项目[(低+高)/2];
可比T;
while(lowhile(items[lo].compareTo(mid)1小点-这里有一个潜在的int溢出:


(lo+hi)/2

编辑:我的坏消息是缺少java标记,很抱歉。。。 下面是C#通用快速排序。。。 不管怎样,我都会把它留给.net读者

乍一看还可以,但是这个普通的怎么样

public class QuickSort<T> where T : IComparable<T>
{
    #region private variable to sort inplace
    readonly private IList<T> itms;
    #endregion private variable to sort inplace

    #region ctor
    private QuickSort() { } // Hide parameterless constructor
    /// <summary>
    /// Constructor requires IList<T> T must implement CompareTo() method.../>
    /// </summary>
    /// <param name="Lst">List<T> of elements to sort</param>
    public QuickSort(IList<T> Lst):this)() { itms = Lst; }
    #endregion ctor

    #region public sort method
    public void Sort() { Sort(0, itms.Count - 1); }
    /// <summary>
    /// Executes QuickSort algorithm
    /// </summary>
    /// <param name="L">Index of left-hand boundary of partition to sort</param>
    /// <param name="R">Index of right-hand boundary of partition to sort</param>
    private void Sort(long L, long R)
    {
        // Calls iSort (insertion-sort) for partitions smaller than 5 elements
        if (R - L < 4) iSort(L, R); 
        else
        {
            long i = (L + R) / 2, j = R - 1;
            // Next three lines to set upper and lower bounds
            if (itms[L].CompareTo(itms[i]) > 0) Swap(L, i);
            if (itms[L].CompareTo(itms[R]) > 0) Swap(L, R);
            if (itms[i].CompareTo(itms[R]) > 0) Swap(i, R);
            Swap(i, j);
            // --------------------------------
            T p = itms[j]; // p = itms[j] is pivot element
            i = L;
            while (true)
            {
                while (itms[++i].CompareTo(p) < 0) {}
                while (itms[--j].CompareTo(p) > 0) {}
                if (j < i) break;
                Swap(i, j);
            }
            Swap(i, R - 1);
            Sort(L, i);     // Sort  Left partition --  HERE WAS TYPO BUG
            Sort(i + 1, R); // Sort Right partition
        }
    }
    #endregion public sort method

    #region private Helper methods
    private void Swap(long L, long R)
    {
        T t = itms[L];
        itms[L] = itms[R];
        itms[R] = t;
    }
    private void iSort(long L, long R)
    {
        for (long i = L; i <= R; i++)
        {
            T t = itms[i];
            long j = i;
            while ((j > L) && (itms[j - 1].CompareTo(t) > 0))
            {
                itms[j] = itms[j - 1];
                j--;
            }
            itms[j] = t;
        }
    }
    #endregion private Helper methods
}
公共类快速排序,其中T:IComparable
{
#要就地排序的区域私有变量
只读私有IList itms;
#要就地排序的endregion私有变量
#区域导体
私有快速排序(){}//隐藏无参数构造函数
/// 
///构造函数要求IList必须实现CompareTo()方法…/>
/// 
///要排序的元素列表
公共快速排序(IList Lst):this)({itms=Lst;}
#端区探测器
#区域公共排序法
public void Sort(){Sort(0,itms.Count-1);}
/// 
///执行快速排序算法
/// 
///要排序的分区左侧边界的索引
///要排序的分区右侧边界的索引
私有无效排序(长L、长R)
{
//对小于5个元素的分区调用iSort(插入排序)
如果(R-L<4)是(L,R);
其他的
{
长i=(L+R)/2,j=R-1;
//接下来的三行设置上限和下限
如果(itms[L]),与(itms[i])>0交换(L,i);
如果(itms[L]。与(itms[R])>0)交换(L,R);
如果(itms[i].与(itms[R])>0)交换(i,R);
互换(i,j);
// --------------------------------
tp=itms[j];//p=itms[j]是枢轴元素
i=L;
while(true)
{
while(itms[++i).与(p)<0{0}
while(itms[--j].CompareTo(p)>0{}
如果(j0))
{
itms[j]=itms[j-1];
j--;
}
itms[j]=t;
}
}
#endregion私有助手方法
}

抓住这个机会,学习如何编写单元测试。(例如,在“junit”上使用Google)。生成大数组并确保它们正确排序,例如:填充了随机数的数组、填充了0、1、Integer.MAX_INT的数组。尝试引发诸如整数溢出和其他奇怪的情况。

下面是一个javascript版本…QuickSort(a、comp、desc)

  • a当然是要排序的数组
  • comp是一个比较函数,它必须接受两个值并返回-1、0或+1,具体取决于这两个参数的排序方式
  • desc是布尔值,用于反转排序顺序

    function QuickSort(a, comp, desc) {
       function defComp(L, R)  {return((L>R)? 1: (L<R)? -1: 0);}
        var cmp = (comp)? comp: defComp; 
        var siz = a.length;
        qSort(0, siz-1);
        if (desc) reverse();
        // ------------------
        function qSort(L, R) {
            if (R - L < 4) {iSort(L, R);} // insertion-sort--
            else {
                var i = parseInt((L+R) /2),  j=R-1;
                if (cmp(a[L], a[i]) > 0) swap(L,i);
                if (cmp(a[L], a[R]) > 0) swap(L,R);
                if (cmp(a[i], a[R]) > 0) swap(i,R);
                swap(i,j);
                // ------------------------------------------
                var p=a[j]; // p=a[j] is pivot
                i=L;
                while (true) {
                    while(cmp(a[++i], p) < 0); 
                    while(cmp(a[--j], p) > 0);    
                    if (j < i) break;
                    swap(i,j);
                }
                swap(i,R-1);
                qSort(L,i);   // Left  Partition
                qSort(i+1,R); // Right Partition
            }
        }
        function swap(L,R) {var t=a[L];  a[L]=a[R];  a[R]=t;}
        function reverse()
           {for(var i=0; i<parseInt(siz/2); i++) swap(i,(siz-i-1));}
        // insertion-sort 
        function iSort(L,R) {
            var j,t;
            for(var i=L; i<=R; i++) {
                t = a[i], j = i;
                while ((j>L) && (cmp(a[j-1], t) > 0))
                    {a[j] = a[j-1]; j--;}
                a[j] = t;
            }
        }
    }
    
    函数快速排序(a、comp、desc){
    函数defComp(L,R){return((L>R)→1:(l0)swap(L,i);
    如果(cmp(a[L],a[R])>0)交换(L,R);
    如果(cmp(a[i],a[R])>0)交换(i,R);
    互换(i,j);
    // ------------------------------------------
    var p=a[j];//p=a[j]是枢轴
    i=L;
    while(true){
    而(cmp(a[++i],p)<0);
    而(cmp(a[--j],p)>0);
    如果(j
公共静态无效快速排序(可比[]a){
快速排序(a,0,a.长度-1);
}
专用静态最终整数截止=10;
专用静态void快速排序(可比[]a,整数低,整数高){
如果(低+截止>高)
插入排序(a、低、高);
否则{
int-middle=(低+高)/2;
如果(a[中间])。与(a[低])相比<0
SWA偏好(a、低、中);
如果(a[高]。与(a[低])相比<0)
SWA偏好(a、低、高);
如果(a[高]。与(a[中])相比<0)
SWA偏好(a、中、高);
SWA偏好(a、中、高-1);
可比支点=a[高-1];
int i,j;
对于(i=低,j=高-1;;){
while(a[++i.)。与(pivot)<0比较
;
while(pivot.compareTo(a[--j])<0)
;
如果(i>=j)
打破
(a,i,j);
}
SWA偏好(a、i、高-1
快速排序(a,low,i-1);//对小元素进行排序
快速排序(a,i+1,高);//对大型元素进行排序
}
}
公共静态首选项(对象[]a,int index1,int index2)
{
对象tmp=a[index1];
a[index1]=a[index2];
a[index2]=tmp;
}
专用静态void insertionSort(可比[]a,int-low,int-high){
对于(int p=low+1;p low&&tmp.compareTo(a[j-1])<0;j--)
a[j]=a[j-1];
a[j]=tmp;
}
}

中,您是否刚刚发布了C#来回答Java问题?我想是的..错过了Java标记..幸运的是,两者之间没有太大区别
function QuickSort(a, comp, desc) {
   function defComp(L, R)  {return((L>R)? 1: (L<R)? -1: 0);}
    var cmp = (comp)? comp: defComp; 
    var siz = a.length;
    qSort(0, siz-1);
    if (desc) reverse();
    // ------------------
    function qSort(L, R) {
        if (R - L < 4) {iSort(L, R);} // insertion-sort--
        else {
            var i = parseInt((L+R) /2),  j=R-1;
            if (cmp(a[L], a[i]) > 0) swap(L,i);
            if (cmp(a[L], a[R]) > 0) swap(L,R);
            if (cmp(a[i], a[R]) > 0) swap(i,R);
            swap(i,j);
            // ------------------------------------------
            var p=a[j]; // p=a[j] is pivot
            i=L;
            while (true) {
                while(cmp(a[++i], p) < 0); 
                while(cmp(a[--j], p) > 0);    
                if (j < i) break;
                swap(i,j);
            }
            swap(i,R-1);
            qSort(L,i);   // Left  Partition
            qSort(i+1,R); // Right Partition
        }
    }
    function swap(L,R) {var t=a[L];  a[L]=a[R];  a[R]=t;}
    function reverse()
       {for(var i=0; i<parseInt(siz/2); i++) swap(i,(siz-i-1));}
    // insertion-sort 
    function iSort(L,R) {
        var j,t;
        for(var i=L; i<=R; i++) {
            t = a[i], j = i;
            while ((j>L) && (cmp(a[j-1], t) > 0))
                {a[j] = a[j-1]; j--;}
            a[j] = t;
        }
    }
}
public static void quicksort( Comparable [ ] a ) {

quicksort( a, 0, a.length - 1 );
}
private static final int CUTOFF = 10;
private static void quicksort( Comparable [ ] a, int low, int high ) {
if( low + CUTOFF > high )
insertionSort( a, low, high );
else {
int middle = ( low + high ) / 2;
if( a[ middle ].compareTo( a[ low ] ) < 0 )
swapReferences( a, low, middle );
if( a[ high ].compareTo( a[ low ] ) < 0 )
swapReferences( a, low, high );
if( a[ high ].compareTo( a[ middle ] ) < 0 )
swapReferences( a, middle, high );
swapReferences( a, middle, high - 1 );
Comparable pivot = a[ high - 1 ];
int i, j;
for( i = low, j = high - 1; ; ) {
while( a[ ++i ].compareTo( pivot ) < 0 )
;
while( pivot.compareTo( a[ --j ] ) < 0 )
;
if( i >= j )
break;
swapReferences( a, i, j );
}
swapReferences( a, i, high - 1
quicksort( a, low, i - 1 ); // Sort small elements
quicksort( a, i + 1, high ); // Sort large elements
 }
}
public static final void swapReferences( Object [ ] a, int index1, int index2 )
{
Object tmp = a[ index1 ];
a[ index1 ] = a[ index2 ];
a[ index2 ] = tmp;
}
private static void insertionSort( Comparable [ ] a, int low, int high ) {
for( int p = low + 1; p <= high; p++ ) {
Comparable tmp = a[ p ];
int j;
for( j = p; j > low && tmp.compareTo( a[ j - 1 ] ) < 0; j-- )
a[ j ] = a[ j - 1 ];
a[ j ] = tmp;
}
}