排序算法在程序中會用到很多,這里介紹幾種常見的排序方法以及比較
冒泡排序:對一個隊列里的數據,挨個進行輪詢和交換,每次輪詢出一個當前最大或者最小的值放在隊尾,然后繼續下次輪詢,輪詢長度-1,就跟冒泡一樣,所以稱為冒泡排序,運算時間復雜度N平方
選擇排序:對一個隊列里的數據,選出當前最大或者最小的值,然后將他與隊首的數據交換,然后從第二個開始,進行相同的操作,運算時間復雜度N平方,但由于他不像冒泡一樣需要不停的交換位置,所以會比冒泡快一些
插入排序:對一個隊列里的數據,從第二個開始,與此位置之前的數據進行比較,形成局部有序的隊列,循環此操作,直到隊尾,運算時間復雜度依然為N平方,但他由于保證了局部的有序性,所以比較的次數會更少一些,相對前兩種會更快
希爾排序:其實就是用步長控制的插入排序,希爾排序通過加大插入排序中元素之間的間隔,并在這些有間隔的元素中進行插入排序,從而讓數據項可以大幅度移動,這樣的方式可以使每次移動之后的數據離他們在最終序列中的位置相差不大,保證數據的基本有序,大大提升了排序速度,運算時間復雜度N*logN
快速排序:對一個隊列,以他隊尾的數據為基準值,先劃分成兩塊數據,一塊都大于這個值,一塊小于這個值,然后對這兩塊進行同樣的操作,這是最快的排序方法,運算時間復雜度N*logN
下面是代碼:
public static void sort(int[] a)
{
long time1,time2;
int c;
time1=System.currentTimeMillis();
// /*冒泡排序*/
// for(int i=a.length-1;i>1;i--)
// {
// for(int j=0;j<i;j++)
// {
//
// if(a[j]<a[j+1])
// {
// c=a[j];
// a[j]=a[j+1];
// a[j+1]=c;
// }
// }
// }
// /*選擇排序*/
// int pos=0;
// for(int i=0;i<a.length-2;i++)
// {
// for(int j=i;j<a.length-1;j++)
// {
// if(a[pos]<a[j+1])
// pos=j+1;
// }
// c=a[i];
// a[i]=a[pos];
// a[pos]=c;
// pos=i+1;
// }
// /*插入排序*/
// for(int i=1;i<a.length;i++)
// {
// c=a[i];
// int m=i-1;
// while(m>=0&&a[m]<c)
// {
// a[m+1]=a[m];
// m--;
// }
// a[m+1]=c;
// }
// /*希爾排序*/
// int h=1;
// int m=0;
// while(3*h+1<a.length)
// h=3*h+1;
// while(h>0)
// {
// for(int i=h;i<a.length;i++)
// {
// c=a[i];
// m=i-h;
// while(m>=0&&a[m]<c)
// {
// a[m+h]=a[m];
// m-=h;
// }
// a[m+h]=c;
//
// }
// h=(h-1)/3;
// }
/*快速排序*/
provide(a,0,a.length-1);
time2=System.currentTimeMillis();
System.out.println("time:"+(time2-time1));
}
/*遞歸調用劃分*/
public static void provide(int[] a,int left,int right)
{
try
{
if(right<=left)
return;
else
{
/*設置基準點*/
int prov=a[right];
/*取得劃分中斷點*/
int par=partitionIt(a,left,right,prov);
/*對劃分后的兩邊再次劃分*/
provide(a,left,par-1);
provide(a,par+1,right);
}
}
catch(Exception e)
{
System.out.println("eer:"+left+"."+right);
}
}
/*劃分算法*/
public static int partitionIt(int[] a,int left,int right,int prov)
{
/*設置左右端點的指針*/
int leftP=left-1;
int rightP=right;
int c;//用于交換的中間變量
/*當左右指針未相遇時繼續操作*/
while(leftP<rightP)
{
/*當左指針的數據小于基準值時跳出*/
while(leftP<a.length-1&&a[++leftP]>prov)
;
/*當右指針的數據大于基準值時跳出*/
while(rightP>leftP&&a[--rightP]<prov)
;
/*左右指針都停下時交換數據*/
c=a[leftP];
a[leftP]=a[rightP];
a[rightP]=c;
}
/*劃分結束,將基準點與指針的相遇點交換*/
c=a[rightP];
a[rightP]=a[right];
a[right]=c;
return leftP;
}