今天的工作完成的早,有空写了排序方法: 

package infon.util.ds; 


import java.util.Random; 


/** 

 * 几种排序算法的比较和选择 

 * 1. 选取排序方法需要考虑的因素: 

 * (1) 待排序的元素数目n; 

 * (2) 元素本身信息量的大小; 

 * (3) 关键字的结构及其分布情况; 

 * (4) 语言工具的条件,辅助空间的大小等。 

 * 2. 小结: (1) 若n较小(n <=50),则可以采用直接插入排序或直接选择排序。由于直接插入排序所需的记录移动操作较直接选择排序多, 

 *       因而当记录本身信息量较大时,用直接选择排序较好。 

 * (2)若文件的初始状态已按关键字基本有序,则选用直接插入或冒泡排序为宜。 

 * (3)若n较大,则应采用时间复杂度为O(nlog2n)的排序方法:快速排序、堆排序或归并排序。 

 *         快速排序是目前基于比较的内部排序法中被认为是最好的方法。 

 * (4)在基于比较排序方法中,每次比较两个关键字的大小之后,仅仅出现两种可能的转移,因此可以用一棵二叉树来描述比较判定过程, 

 *         由此可以证明:当文件的n个关键字随机分布时,任何借助于"比较"的排序算法,至少需要O(nlog2n)的时间。 

 * (5) 当记录本身信息量较大时,为避免耗费大量时间移动记录,可以用链表作为存储结构。 

 * 

 * 效率:从上往下递减 

 * 排序名称        复杂度 

 * 冒泡排序        O(N^2) 

 * 选择排序        O(N^2) 

 * 插入排序        O(N^2) 

 * 归并排序        

 * 希尔排序        O(N*(logN)^2) 

 * 快速排序        O(N*(logN)^2) 

 * 

 * @author infon 

 * 

 */ 

public class Sort { 

    /** 

     * 插入排序(Insertion Sort) 

     *  1. 基本思想: 

     * 每次将一个待排序的数据元素,插入到前面已经排好序的数列中的适当位置,使数列依然有序;直到待排序数据元素全部插入完为止。 

     *  2. 排序过程: 

     * 【示例】: 

     * [初始关键字] [49] 38 65 97 76 13 27 49 

     * J=2(38) [38 49] 65 97 76 13 27 49 

     * J=3(65) [38 49 65] 97 76 13 27 49 

     * J=4(97) [38 49 65 97] 76 13 27 49 

     * J=5(76) [38 49 65 76 97] 13 27 49 

     * J=6(13) [13 38 49 65 76 97] 27 49 

     * J=7(27) [13 27 38 49 65 76 97] 49 

     * J=8(49) [13 27 38 49 49 65 76 97] 

     * 

     * @param src 

     */ 

    public int[] insertSort(int[] src) { 

        int in,out; 

        for(out=1;out<src.length;out++){ 

            int tmp=src[out]; 

            in=out; 

            while(in>0&&src[in-1]>=tmp){ 

                src[in]=src[in-1]; 

                --in; 

            } 

            src[in]=tmp; 

        } 

        return src; 

    } 

    //---------------------------------------------------------------- 

     

    /** 

     * 希尔排序 

     */ 

    public int[] shellSort(int[] src) { 

        int inner, outer; 

        int temp; 


        int h = 1; // find initial value of h 

        while (h <= src.length / 3) 

            h = h * 3 + 1; // (1, 4, 13, 40, 121, ...) 


        while (h > 0) // decreasing h, until h=1 

        { 

            // h-sort the file 

            for (outer = h; outer < src.length; outer++) { 

                temp = src[outer]; 

                inner = outer; 

                // one subpass (eg 0, 4, 8) 

                while (inner > h - 1 && src[inner - h] >= temp) { 

                    src[inner] = src[inner - h]; 

                    inner -= h; 

                } 

                src[inner] = temp; 

            } // end for 

            h = (h - 1) / 3; // decrease h 

        } // end while(h>0) 

        return src; 

    } // end shellSort() 

    // -------------------------------------------------------------- 


    /** 

     * 选择排序 

     * 1. 基本思想: 

     * 每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。 

     * 2.排序过程: 【示例】: 

     *  初始关键字   [49 38 65 97 76 13 27 49] 

     *  第一趟排序后 13 [38 65 97 76 49 2749] 

     *  第二趟排序后 13 27 [65 97 76 49 38 49] 

     *  第三趟排序后 13 27 38 [97 76 49 65 49] 

     *  第四趟排序后 13 27 38 49 [49 97 65 76] 

     *  第五趟排序后 13 27 38 49 49 [97 97 76] 

     *  第六趟排序后 13 27 38 49 49 76 [76 97] 

     *  第七趟排序后 13 27 38 49 49 76 76 [ 97] 

     *  最后排序结果 13 27 38 49 49 76 76 97 

     * 

     * @param src 

     * @return 

     */ 

    public int[] selectSort(int src[]) { 

        for(int i=0;i<src.length;i++){ 

            int index=i; 

            for(int j=i+1;j<src.length;j++){ 

                if(src[index]>src[j]){ 

                    index=j; 

                }//~end if 

            }//~end for2 

            if(i!=index){ 

                int tmp; 

                tmp=src[i]; 

                src[i]=src[index]; 

                src[index]=tmp; 

            }//~end if 

        }//~end for1 

        return src; 

    } 

    //----------------------------------------------------------------------------------- 


    /** 

     * 

     * 冒泡排序(BubbleSort) 

     * 1. 基本思想: 

     *   两两比较待排序数据元素的大小,发现两个数据元素的次序相反时即进行交换,直到没有反序的数据元素为止。 

     * 2. 排序过程: 

     *   设想被排序的数组R[1..N]垂直竖立,将每个数据元素看作有重量的气泡,根据轻气泡不能在重气泡之下的原则, 

     * 从下往上扫描数组R,凡扫描到违反本原则的轻气泡,就使其向上"漂浮",如此反复进行,直至最后任何两个气泡都是轻者在上,重者在下为止。 

     * 【示例】: 

     *  49 13 13 13 13 13 13 13 

     *  38 49 27 27 27 27 27 27 

     *  65 38 49 38 38 38 38 38 

     *  97 65 38 49 49 49 49 49 

     *  76 97 65 49 49 49 49 49 

     *  13 76 97 65 65 65 65 65 

     *  27 27 76 97 76 76 76 76 

     *  49 49 49 76 97 97 97 97 

     * 

     * @param src 

     * @return 

     */ 

    public int[] bubbleSort(int[] src){ 

        for(int i=0;i<src.length;i++){ 

            boolean isChange=false; // 

            for(int j=src.length-1;j>i;j--){ 

                if(src[j]<src[j-1]){ 

                    int tmp=src[j]; 

                    src[j]=src[j-1]; 

                    src[j-1]=tmp; 

                    isChange=true; 

                }//~end if 

            }//~end for2 

            if(!isChange)return src;  //本趟排序未发生交换,提前终止算法 

        }//~end for1 

        return src; 

    }//~end bubbleSort() 

     

    //------------------------------------------------------------------------------------ 

     

    /** 

     * 快速排序(Quick Sort) 

     * 1. 基本思想: 在当前无序区R[1..H]中任取一个数据元素作为比较的"基准"(不妨记为X), 

     * 用此基准将当前无序区划分为左右两个较小的无序区:R[1..I-1]和R[I+1..H],且左边的无序子区中数据元素均小于等于基准元素, 

     * 右边的无序子区中数据元素均大于等于基准元素,而基准X则位于最终排序的位置上,即R[1..I-1] 

     * ≤X.Key≤R[I+1..H](1≤I≤H),当R[1..I-1]和R[I+1..H]均非空时,分别对它们进行上述的划分过程, 

     * 直至所有无序子区中的数据元素均已排序为止。 

     * 2. 排序过程: 

     * 【示例】: 

     * 初始关键字   [49 38 65 97 76 13 27 49] 

     * 第一次交换后 [27 38 65 97 76 13 49 49] 

     * 第二次交换后 [27 38 49 97 76 13 65 49] 

     * J向左扫描,位置不变,第三次交换后 [27 38 13 97 76 49 65 49] 

     * I向右扫描,位置不变,第四次交换后 [27 38 13 49 76 97 65 49] 

     * J向左扫描 [27 38 13 49 76 97 65 49] 

     *(一次划分过程) 

     * 初始关键字 [49 38 65 97 76 13 27 49] 

     * 一趟排序之后 [27 38 13] 49 [76 97 65 49] 

     * 二趟排序之后 [13] 27 [38] 49 [49 65]76 [97] 

     * 三趟排序之后 13 27 38 49 49 [65]76 97 

     * 最后的排序结果 13 27 38 49 49 65 76 97 

     * 

     * 改进后的算法枢轴不再是第一个或者是最后一个,而是取第一个、最后一个及中间一个的中间值 

     * 如果要排序的基数少于10的话,我们就用插入排序,效果会更理想一些 

     * 

     * @param src 

     * @return 

     */ 

    public int[] quickSort(int[] src) { 

        recQuickSort(src,0, src.length - 1); 

        return src; 

    } 


    private void recQuickSort(int[] src,int left, int right) { 

        int size = right-left+1; 

          if(size < 10)                   // insertion sort if small 

              insertSort(src);         

        else { 

            int pivot = medianOf3(src,left, right); 

            int index = partition(src,left, right, pivot); 

            

            recQuickSort(src,left, index - 1); 

            recQuickSort(src,index + 1, right); 

        } 

    } 


    private int partition(int []src,int left, int right, int pivot) { 

        int leftPtr = left - 1; // left (after ++) 

        int rightPtr = right; // right-1 (after --) 

        while (true) { // find bigger item 

            while (src[++leftPtr] < pivot) 

                ; // (nop) 

            // find smaller item 

            while (rightPtr > 0 && src[--rightPtr] > pivot) 

                ; // (nop) 


            if (leftPtr >= rightPtr) // if pointers cross, 

                break; // partition done 

            else 

                // not crossed, so 

                swap(src,leftPtr, rightPtr); // swap elements 

        } // end while(true) 

        swap(src,leftPtr, right); // restore pivot 

        return leftPtr; 

    }// ~end method partition 


    public void swap(int []src,int dex1, int dex2) // swap two elements 

    { 

        int temp = src[dex1]; // A into temp 

        src[dex1] = src[dex2]; // B into A 

        src[dex2] = temp; // temp into B 

    } // end swap() 

     

    public int medianOf3(int[]src,int left, int right) 

    { 

    int center = (left+right)/2; 

                                     // order left & center 

    if( src[left] > src[center] ) 

       swap(src,left, center); 

                                     // order left & right 

    if( src[left] > src[right] ) 

       swap(src,left, right); 

                                     // order center & right 

    if( src[center] > src[right] ) 

       swap(src,center, right); 


    swap(src,center, right-1);           // put pivot on right 

    return src[right-1];        // return median value 

    }  // end medianOf3() 

//-------------------------------------------------------------- 

    // ****************************** end quickSort 

     

    /** 

     * @param args 

     */ 

    public static void main(String[] args) { 

        // TODO Auto-generated method stub 

        int[] src = new int[] { 49, 38, 65, 97, 76, 13, 27, 49 }; 

        int[] result=new int[src.length]; 

        

        Sort sort = new Sort(); 

        

        result=sort.insertSort(src.clone());  

        System.out.print("insertSort: "); 

        print(result); 

        

        result = sort.selectSort(src.clone()); 

        System.out.print("selectSort: "); 

        print(result); 

        

        result = sort.quickSort(src.clone()); 

        System.out.print("quickSort: "); 

        print(result); 

        

        result = sort.bubbleSort(src.clone()); 

        System.out.print("bubbleSort: "); 

        print(result); 

        

        result = sort.shellSort(src.clone()); 

        System.out.print("shellSort: "); 

        print(result); 

        //测试排序所需要的时间 

        test(10000); 

    } 

     

    public static void print(int []src){ 

        for (int i = 0; i < src.length; i++) { 

            if(i==src.length-1){ 

                System.out.println(src[i]); 

            }else{ 

                System.out.print(src[i] + ","); 

            } 

            if(i%10==0&&i!=0)System.out.println(); 

        } 

    } 

     

    /** 

     * 

     * @param num 

     *        num为测试数据的数量 

     */ 

    public static void test(int num){ 

        long start=System.currentTimeMillis(); 

        Sort sort = new Sort(); 

        int[] src = new int[num]; 

        Random rand=new Random(); 

        for(int i=0;i<src.length;i++){ 

            src[i]=Math.abs(rand.nextInt()%10000); 

        } 

        

        int[] result; 

        

        start = System.currentTimeMillis(); 

        result=sort.insertSort(src.clone()); 

        System.out.println("insertSort: " + (System.currentTimeMillis() - start)); 

        

        start = System.currentTimeMillis(); 

        result = sort.selectSort(src.clone()); 

        System.out.println("selectSort: " + (System.currentTimeMillis() - start)); 

        

        start = System.currentTimeMillis(); 

        result = sort.bubbleSort(src.clone()); 

        System.out.println("bubbleSort: " + (System.currentTimeMillis() - start)); 

        

        start = System.currentTimeMillis(); 

        result = sort.shellSort(src.clone()); 

        System.out.println("shellSort: " + (System.currentTimeMillis() - start)); 

        

        start = System.currentTimeMillis(); 

        result = sort.quickSort(src.clone()); 

        System.out.println("quickSort: " + (System.currentTimeMillis() - start)); 

    }//~end test 

}