排序方法(java语言)

排序法

 平均时间

最差情形

稳定度

额外空间

备注

冒泡

 O(n2)

  O(n2)

 稳定

O(1)

n小时较好

选择

 O(n2)

 O(n2)

不稳定

O(1)

n小时较好

插入

 O(n2)

 O(n2)

稳定

O(1)

大部分已排序时较好

基数

O(logrd)

O(logrd)

稳定

O(n)

d是关键字项数(0-9),

r是基数(个十百)

快速

O(nlogn)

O(n2)

不稳定

O(nlogn)

n大时较好

归并

O(nlogn)

O(nlogn)

稳定

O(1)

n大时较好

O(nlogn)

O(nlogn)

不稳定

O(1)

n大时较好

希尔

 

 

 

 

 

 

1.    冒泡排序

冒泡排序是最慢的排序算法.在实际运用中它是效率最低的算法.

a)       原理:将序列划分无序和有序区,不断通过交换较大元素至无序区尾完成排序.

b)       要点:在要排序的一组数中,对当前还没有排好序的范围内的全部的数,自上而下对相邻两个数依次进行比较和调整,让较大的数据往下沉,较小的数网上冒.即: 每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换. 设计交换判断条件,提前结束以排好序的序列循环。

publicclass Sort {

   

    publicstaticvoid main(String[]args) {

       int[] arraySort ={77,55,22,88,11,99,66,44,33};

      

       //排序前

       System.out.print("排序前:");

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

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

       }

      

       /**

        * 冒泡排序

        * 思路:是将最小的数据项放在数组的最开始(数组下标为0),并将最大的数据项放在数组的最后(数组下标为nElems-1).

        *      外层for循环的计数器out从数组的最后开始,out等于nElems-1,没经过一次循环out减一.

        *      下标大于out的数据项都已经是排好序的.变量out在没完成一次内部循环后就左移一位,因此算法就不在处理那些已经排好序的数据了.

        *      内层for循环计数器in从数组的最开始算起,in=0,没完成一次内部循环体加一,当它等于out时结束一次循环.在内层for循环中,

        *      数组下标为inin+1的两个数据项做比较,如果下标为in的数据项大于下标为in+1的数据项,则交换两个数据项.

        */

 

       int out,in;

       for(out = arraySort.length-1; out > 0;out--){

           for(in = 0; in <out; in++){

              if(arraySort[in] >arraySort[out]){

                  int temp;

                  temp= arraySort[in];

                  arraySort[in]= arraySort[out];

                  arraySort[out]= temp;

              }

           }

       }

      

       //排序后

       System.out.print("排序后:");

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

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

       }

    }

}

2.    选择排序

原理: 将序列划分为无序和有序区,寻找无序区中的最小值和无序区的首元素交换,有序区扩大一个,循环最终完成全部排序.

 

描述: 在要排序的一组数中,选出最小的一个数与第一个位置的数交换;然后在剩下的数当中再找最小的与第二个位置的数交换,如此循环到倒数第二个数和最后一个数比较为止。

publicclass Sort {

    publicstaticvoid main(String[]args) {

       int[] arraySort ={77,55,22,88,11,99,66,44,33};

      

       //排序前

       System.out.print("排序前:");

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

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

       }

      

       /**

       * 选择排序

       * 外层循环用循环变量out,从数组开头开始(数组下标为0)向高位增长

       * 内层循环用循环变量in,out所指位置开始,同样是向右移动.

       * 在每一个in的新位置,数据项a[in]a[min]进行比较.如果a[in]更小,min被赋值为in的值.

       * 在内层循环的最后,min指向最小的数据项,然后交换outmin指向的数组的数据项.

       */

       int out;

       int in;

       int min;

       for(out = 0; out <arraySort.length; out++){

           min =out;

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

              if(arraySort[in] <arraySort[min]){

                  min= in;

              }

             

              int temp =arraySort[out];

              arraySort[out]= arraySort[min];

              arraySort[min]= temp;

           }

       }

      

       //排序后

       System.out.print("排序后:");

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

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

       }

    }

}

 

3.    插入排序

原理:将数组分为无序区和有序区两个区,然后不断将无序区的第一个元素按大小顺序插入到有序区中去,最终将所有无序区元素都移动到有序区完成排序。

要点:设立哨兵,作为临时存储和判断数组边界之用。

publicclass Sort {

   

    publicstaticvoid main(String[]args) {

       int[] arraySort ={77,55,22,88,11,99,66,44,33};

      

       //排序前

       System.out.print("排序前:");

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

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

       }

      

       /**

       * 插入排序

       * 在外层的for循环中,out变量从1开始,向右移动.它标记了未排序部分的最左端的数据.

       * 在内层的while循环中,in变量从out变量开始,向左移动,知道temp变量小于in所指的数组数据项,或者它已经不能再往左移动为止.

        * while循环的每一趟都向移动了一个已排序的数据项.

        */

       int out;

       int in;

 

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

           int temp =arraySort[out];

           in = out;

           while(in > 0&& arraySort[in - 1] >= temp){

              arraySort[in]= arraySort[in-1];

              --in;

           }

           arraySort[in]= temp;

       }

      

       //排序后

       System.out.print("排序后:");

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

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

       }

    }

}

 

4.    归并排序

归并排序比堆排序稍微快一点,但是需要比堆排序多一倍的内存空间,因为它需要一个额外的数组

publicclass MergeApp {

    publicstaticvoid main(String[] args) {

       int[] arrayA = {23,47,85,98};

       int[] arrayB = {7,14,35,26,56,74};

       int[] arrayC =newint[10];

      

       merge(arrayA,4,arrayB,6,arrayC);

       display(arrayC, 10);

    }

   

    publicstaticvoid merge(int[] arrayA,int sizeA,int[] arrayB,int sizeB,int[] arrayC){

       int aDex = 0;

       int bDex = 0;

       int cDex = 0;

      

       /**

        * 沿着数组arrayA和数组arrayB,比较他们的数据项,并且复制他们中最小的数据项到数组arrayC.

        */

       while(aDex < sizeA && bDex < sizeB){

           if(arrayA[aDex] < arrayB[bDex]){

              arrayC[cDex++] = arrayA[aDex++];

           }else{

              arrayC[cDex++] = arrayB[bDex++];

           }

       }

      

       /**

        * 当数组arrayB中所有的数据项全部移除,而数组arrayA还有剩余的数据项的情况.

        * 这个循环把剩余的数据项直接从数组arrayA中复制到数组arrayC.

        */

       while(aDex < sizeA){

           arrayC[cDex++] = arrayA[aDex++];

       }

      

           /**

        * 当数组arrayA中所有的数据项全部移除,而数组arrayB还有剩余的数据项的情况.

            * 这个循环把剩余的数据项直接从数组arrayB中复制到数组arrayC.

            */

           while(bDex < sizeB){

               arrayC[cDex++] =arrayB[bDex++];

           }

        }

       

        publicstaticvoid display(int[] theArray,int size){

           for(int i = 0; i <size; i++){

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

            }

        }

}

 

5.    快速排序

原理:不断寻找一个序列的中点,然后对中点左右的序列递归的进行排序,直至全部序列排序完成,使用了分治的思想.

快速排序是一个就地排序,分而治之,大规模递归的算法。从本质上来说,它是归并排序的就地版本。快速排序可以由下面四步组成。

(1) 如果不多于1个数据,直接返回。

(2) 一般选择序列最左边的值作为支点数据。即temp=a[0];

(3) 将序列分成2部分,一部分都大于支点数据,另外一部分都小于支点数据。

(4) 对两边利用递归排序数列。

 

快速排序比大部分排序算法都要快。尽管我们可以在某些特殊的情况下写出比快速排序快的算法,但是就通常情况而言,没有比它更快的了。快速排序是递归的,对于内存非常有限的机器来说,它不是一个好的选择。

 

publicclass Sort {

   

    staticvoid quick_sort(int s[], int l,int r){

        if (l < r){

            int i = l, j = r, temp = s[l];

            while (i < j){

              //从右向左找第一个小于temp的数

                while(i < j && s[j] >= temp){

j--;

                }

                if(i < j){

                      s[i++] = s[j];

                }

              //从左向右找第一个大于等于temp的数

                while(i < j && s[i] < temp){

                    i++;

                }

                if(i < j){

                    s[j--] = s[i];

                }

            }

            s[i] = temp;

           

            if(i - l > 1){

              //递归调用,temp前面的数据项完成排序

                quick_sort(s, l, i - 1);

            }

            if(r - j > 1){

              //递归调用,temp后面的数据项完成排序

                quick_sort(s, i + 1, r);

            }

 

        }

    }

   

    publicstaticvoid main(String[]args) {

       int[] arraySort ={77,55,22,88,11,99,66,44,33};

      

       //排序前

       System.out.print("排序前:");

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

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

       }

      

       quick_sort(arraySort,0,arraySort.length-1);

      

       //排序后

       System.out.print("排序后:");

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

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

       }

    }

}

6.    基数排序

原理:将数字按位数划分出n个关键字,每次针对一个关键字进行排序,然后针对排序后的序列进行下一个关键字的排序,循环至所有关键字都使用过则排序完成。

要点:对关键字的选取,元素分配收集。

 

基数排序和通常的排序算法并不走同样的路线。它是一种比较新颖的算法,但是它只能用于整数的排序,如果我们要把同样的办法运用到浮点数上,我们必须了解浮点数的存储格式,并通过特殊的方式将浮点数映射到整数上,然后再映射回去,这是非常麻烦的事情,因此,它的使用同样也不多。而且,最重要的是,这样算法也需要较多的存储空间。

 

publicclass Sort {

    publicstaticvoid main(String[]args) 

       int[] arraySort ={77,55,22,88,11,99,66,44,33};

      

       //排序前

       System.out.print("排序前:");

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

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

       }

         

       arraySort = radixSort(arraySort);

      

         System.out.println();

       //排序后

       System.out.print("排序后:");

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

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

       }

   

     

    publicstaticint[] radixSort(int[] a) 

   

        int[] b =newint[a.length]; 

         

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

            b[i] =a[i]; 

             

        for(int i=1; i<=a.length; i++) 

            b = countSort(b,i); 

         

        return b; 

   

     

    publicstaticint[] countSort(int[] a, int k) 

   

        int[] b =newint[a.length]; 

        int[] c =newint[10]; 

         

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

            b[i] =0; 

         

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

            c[i] =0; 

         

        int s = 1; 

        for(int i=0; i<k;i++) 

            s = s *10; 

         

        int temp1 = 0; 

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

       

            temp1 =a[i]%s; 

            temp1 =temp1 * 10 / s; 

             

           c[temp1] = c[temp1] + 1; 

       

         

        for(int i=1; i<c.length; i++) 

            c[i] =c[i] + c[i-1]; 

         

        int temp2 = 0; 

        for(int i=a.length-1; i>=0;i--) 

       

            temp1 =a[i]; 

            temp2 =a[i]%s; 

            temp2 =temp2 * 10 / s; 

              

           b[c[temp2]-1] = temp1; 

           c[temp2] = c[temp2] - 1; 

       

        return b; 

   

}

 

7.    希尔排序

原理:又称增量缩小排序。先将序列按增量划分为元素个数相同的若干组,使用直接插入排序法进行排序,然后不断缩小增量直至为1,最后使用直接插入排序完成排序。

要点:增量的选择以及排序最终以1为增量进行排序结束。

 

希尔排序基于插入排序,通过加大排序中元素之间的间隔,并在这些间隔的元素进行插入排序,从而使数据项能大跨度地移动.

 

publicclass Sort {

   

    publicstaticvoid main(String[]args) {

       int[] arraySort ={77,55,22,88,11,99,66,44,33};

      

       //排序前

       System.out.print("排序前:");

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

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

       }

      

       int inner;

       int outer;

       int temp;

      

       inth = 1;

       while(h <= arraySort.length/3){

           h =h * 3 + 1;

       }

      

       while(h > 0){

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

              temp =arraySort[outer];

              inner= outer;

             

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

                  arraySort[inner]= arraySort[inner-h];

                  inner-= h;

              }

              arraySort[inner]= temp;

           }

           h = (h-1)/3;

       }

      

       //排序后

       System.out.print("排序后:");

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

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

       }

    }

}

8.    堆排序

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值