八大排序算法总结(java版)

来源:互联网 发布:扫描软件排行 编辑:程序博客网 时间:2024/06/04 18:19

Java 写的八大排序算法总结

需要完整代码的可以在下面链接下载不要积分的

http://download.csdn.net/detail/u010275119/5451321

1//冒泡排序

原理是临近的数字两两进行比较,按照从小到大或者从大到小的顺序进行交换,

这样一趟过去后,最大或最小的数字被交换到了最后一位,

然后再从头开始进行两两比较交换,直到倒数第二位时结束

         publicstatic int[] getBubbleSort(int[] x){

                   for(inti=0;i<x.length-1;i++){

                            for(intj=0;j<x.length-1-i;j++){

                                     if(x[j]>x[j+1]){

                                               inttemp=x[j];

                                               x[j]=x[j+1];

                                               x[j+1]=temp;

                                     }

                            }

                   }

         returnx;

         }

冒泡排序是稳定的排序,平均和最坏时间复杂度是O(n^2)

2//插入排序

插入排序就是每一步都将一个待排数据按其大小插入到已经排序的数据中的适当位置,直到全部插入完毕。 
插入排序方法分直接插入排序和折半插入排序两种,这里只介绍直接插入排序 

public static int[] getInsSort(int[] x){

                   for(inti=1;i<x.length;i++){

                            intkey=x[i];//key为待排数

                            intj=i-1;

                            for(;j>=0;j--){

                                     if(key<x[j])

                                               x[j+1]=x[j];

                                     else

                                     break;

                            }

                            x[j+1]=key;

                   }

         returnx;

         }

插入排序是稳定的排序,平均和最坏时间复杂度是O(n^2)。最好的时间复杂度是O(n),对应于全部排好序的情况

3//堆排序

         publicstatic int[] getHeapSort(int[] x){

                   for(inti = x.length/2; i >= 1; i--){

                            getHeapAdjust(x,i,x.length-1);       

                   }

                   for(inti = x.length-1; i > 1; i--){//从最后一个开始

                            intt=x[1];

                            x[1]=x[i];

                            x[i]=t;

                            getHeapAdjust(x,1, i-1);    

                   }

         returnx; 

         }

//建立大根堆

         publicstatic void getHeapAdjust(int[] x,int k,int m){

                   inttemp=x[k];

                   intj=2*k;

                   for(;j <= m; j *= 2){

                            if(j< m && x[j] < x[j+1])

                                     j++;

                            if(temp>= x[j])

                                     break;

                            x[k]=x[j];

                            k=j;           

                   }

                   x[k]=temp;

         }

堆排序是原地排序,但是不是稳定排序。时间复杂度O(nlogn)

4//快速排序

原理,通过一趟扫描将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列

         publicstatic int[] QKSort(int[] x,int low,int high){

                   if(low<high){

                            intpos=QKPass(x,low,high);

                            QKSort(x,low,pos-1);

                            QKSort(x,pos+1,high);

                   }

         returnx;

         }

         publicstatic int QKPass(int[] x,int left,int right){

                   intlow=left,high=right;

                   intkey=x[left];

                   while(low<high){

                            while(low<high&&key<=x[high])

                                     high--;

                            if(low<high){

                                     x[low]=x[high];

                                     low++;

                            }

                            while(low< high && x[low]<key)

                                     low++;

                            if(low<high){

                                     x[high]=x[low];

                                     high--;

                            }       

                   }

                   x[low]=key;

         returnlow;

         }

快速排序是不稳定的排序,最差时间复杂度是O(n^2),平均时间复杂度是O(nlogn)

5//简单选择排序

就是直接从待排序数组里选择一个最小(或最大)的数字,每次都拿一个最小数字出来,

顺序放入新数组,直到全部拿完

         publicstatic int[] getSelectSort(int[] x){

                   for(inti=0;i<x.length;i++){

                            intmin=i;

                            for(intj=i+1;j<x.length;j++){

                                     if(x[j]<x[min])

                                               min=j;

                            }                

                            if(min!=i){

                                     inttemp=x[i];

                                     x[i]=x[min];

                                     x[min]=temp;

                            }

                   }       

         returnx;

         }

选择排序是不稳定的,因为,在一趟选择,如果当前元素比一个元素小,而该小的元素又出现在一个和当前元素相等的元素后面,那么交换后稳定性就被破坏了。

6//归并排序de递归算法

原理,把原始数组分成若干子数组,对每一个子数组进行排序,

继续把子数组与子数组合并,合并后仍然有序,直到全部合并完,形成有序的数组

         publicstatic int[] getMergeSort(int[] x){

                   MSort(x,x,0,x.length-1);

                   returnx;

         }

         publicstatic void MSort(int[] r1,int[] r,int low,int high){

                   intmid;

                   int[]r2=new int[r.length];

                   if(low==high)

                            r[low]=r1[low];

                   else{

                            mid=(low+high)/2;

                            MSort(r1,r2,low,mid);

                            MSort(r1,r2,mid+1,high);

                            Merge(r2,r,low,mid,high);

                   }

         }

         publicstatic void Merge(int[] r1,int[] r,int low,int mid,int high){

                   inti=low,j=mid+1,k=low;

                   while((i<=mid)&&(j<=high)){

                            if(r1[i]<=r1[j])

                                     r[k]=r1[i++];

                            else

                                     r[k]=r1[j++];

                            k++;

                   }

                   while(i<=mid){

                            r[k]=r1[i];

                            k++;

                            i++;

                   }

                   while(j<=high){

                            r[k]=r1[j];

                            k++;

                            j++;

                   }

                  

         }

合并过程中我们可以保证如果两个当前元素相等时,我们把处在前面的序列的元素保存在结果序列的前面,这样就保证了稳定性。所以,归并排序也是稳定的排序算法。时间复杂度是O(nlogn)可以在空间复杂度O(1)的条件下实现归并排序

7//基数排序算法(桶排序)

原理类似桶排序,这里总是需要10个桶,多次使用

首先以个位数的值进行装桶,即个位数为1则放入1号桶,为9则放入9号桶,暂时忽视十位数

         publicstatic int[] getBucketSort(int[] number){

         intk=0;

         intn=1;

         intm=1;//控制键值排序依据在哪一位

         int[][]temp = new int[number.length][number.length];

         int[]order = new int[number.length];

         while(m<= number.length) {

                   for(inti = 0; i < number.length; i++) {

                            intlsd = ((number[i] / n) % 10);

                            temp[lsd][order[lsd]]= number[i];

                            order[lsd]++;

                   }

                   for(inti = 0; i < number.length; i++) {

                            if(order[i]!= 0)

                            for(intj = 0; j < order[i]; j++) {

                                     number[k]= temp[i][j];

                                     k++;

                            }

                   order[i]= 0;

                   }

         n*= 10;

         k= 0;

         m++;

         }

         returnnumber;

         }

桶排序的平均时间复杂度为线性的O(N+C),其中C=N*(logN-logM)。如果相对于同样的N,桶数量M越大,其效率越高,最好的时间复杂度达到O(N)。当然桶排序的空间复杂度为O(N+M),如果输入数据非常庞大,而桶的数量也非常多,则空间代价无疑是昂贵的。此外,桶排序是稳定的。

1,桶排序是稳定的

2,桶排序是常见排序里最快的一种,比快排还要快…大多数情况下

3,桶排序非常快,但是同时也非常耗空间,基本上是最耗空间的一种排序算法

 

8//希尔排序

参见下面链接

http://baike.baidu.com/view/178698.htm?fromId=2217047

         publicstatic void getShellSort(int[] a) {

                   inti,k;

                   intTemp;

                   booleanChange;

                   intDataLength; // 分割集合的间隔长度

                   intPointer; // 进行处理的位置

                   DataLength= (int) (a.length-1) / 2;

                   while(DataLength != 0){ // 数列仍可进行分割

                            for(int j = DataLength; j < a.length-1; j++) {

                                     Change= false;

                                     Temp= a[j];

                                     Pointer= j - DataLength; // 计算进行处理的位置

                                     //进行集合内数值的比较与交换值

                                     while(Temp < a[Pointer] && Pointer >= 0 && Pointer <=a.length-1) {

                                               a[Pointer+ DataLength] = a[Pointer];

                                               //计算下一个欲进行处理的位置

                                               Pointer= Pointer - DataLength;

                                               Change= true;

                                               if(Pointer < 0 || Pointer > a.length-1)

                                               break;

                                     }

                                     //与最后的数值交换

                                     a[Pointer+ DataLength] = Temp;  

                            }

                   DataLength= DataLength / 2; // 计算下次分割的间隔长度

                   }

         }

希尔排序是不稳定的。由于多次插入排序,我们知道一次插入排序是稳定的,不会改变相同元素的相对顺序,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,所以shell排序是不稳定的。使用希尔增量时,最坏运行时间是O(n^2),使用Hibbard增量时,最坏运行时间是O(n^3/2)



原创粉丝点击