亚洲精品中文字幕无乱码_久久亚洲精品无码AV大片_最新国产免费Av网址_国产精品3级片

java語言

Java的五大排序算法

時間:2024-09-09 20:06:03 偲穎 java語言 我要投稿
  • 相關推薦

Java常用的五大排序算法

  排序算法的使用可以讓我們更方便的進行排序,下面是小編給大家提供的Java常用的五大排序算法,大家可以參考閱讀。

  Java的五大排序算法1

  1、Java排序算法之選擇排序

  選擇排序的基本思想是遍歷數(shù)組的過程中,以i代表當前需要排序的序號,則需要在剩余的[i…n-1]中找出其中的最小值,然后將找到的最小值與i指向的值進行交換。因為每一趟確定元素的過程中都會有一個選擇最大值的子流程,所以人們形象地稱之為選擇排序。

  舉個實例來看看:

  1.初始:[38,17,16,16,7,31,39,32,2,11]

  2.3.i=0:[2,17,16,16,7,31,39,32,38,11](0th[38]<->8th[2])

  6.7.i=2:[2,7,11,16,17,31,39,32,38,16](2nd[11]<->9th[16])

  12.13.i=5:[2,7,11,16,16,17,39,32,38,31](5th[31]<->9th[17])

  16.17.i=7:[2,7,11,16,16,17,31,32,38,39](無需交換)

  18.19.i=8:[2,7,11,16,16,17,31,32,38,39](無需交換)

  20.21.i=9:[2,7,11,16,16,17,31,32,38,39](無需交換)

  由例子可以看出,選擇排序隨著排序的進行(i逐漸增大),比較的次數(shù)會越來越少,但是不論數(shù)組初始是否有序,選擇排序都會從i至數(shù)組末尾進行一次選擇比較,所以給定長度的數(shù)組,選擇排序的比較次數(shù)是固定的:1+2+3+…+n=nx(n+1)/2,而交換的次數(shù)則跟初始數(shù)組的順序有關,如果初始數(shù)組順序為隨機,則在最壞情況下,數(shù)組元素將會交換n次,最好的情況下則可能0次(數(shù)組本身即為有序)。

  由此可以推出,選擇排序的時間復雜度和空間復雜度分別為O(n2)和O(1)(選擇排序只需要一個額外空間用于數(shù)組元素交換)。

  實現(xiàn)代碼:

  1./xx

  2.xSelectionSorting

  3.x/

  4.SELECTION(newSortable(){

  5.public

  6.intlen=array.length;

  7.for(inti=0;i<len;i++){

  8.intselected=i;

  9.for(intj=i+1;j<len;j++){

  10.intcompare=array[j].compareTo(array[selected]);

  11.if(compare!=0&&compare<0==ascend){

  12.selected=j;

  13.}

  14.}

  15.16.exchange(array,i,selected);

  17.}

  18.}

  19.})

  2、Java排序算法之插入排序

  插入排序的基本思想是在遍歷數(shù)組的過程中,假設在序號i之前的元素即[0i-1]都已經(jīng)排好序,本趟需要找到i對應的元素x的正確位置k,并且在尋找這個位置k的過程中逐個將比較過的元素往后移一位,為元素x"騰位置",最后將k對應的元素值賦為x,插入排序也是根據(jù)排序的特性來命名的。

  以下是一個實例,紅色標記的數(shù)字為插入的數(shù)字,被劃掉的數(shù)字是未參與此次排序的元素,紅色標記的數(shù)字與被劃掉數(shù)字之間的元素為逐個向后移動的元素,比如第二趟參與排序的元素為[11,31,12],需要插入的元素為12,但是12當前并沒有處于正確的位置,于是我們需要依次與前面的元素31、11做比較,一邊比較一邊移動比較過的元素,直到找到第一個比12小的元素11時停止比較,此時31對應的索引1則是12需要插入的位置。

  3、Java排序算法之冒泡排序

  冒泡排序可以算是最經(jīng)典的排序算法了,記得小弟上學時最先接觸的也就是這個算法了,因為實現(xiàn)方法最簡單,兩層for循環(huán),里層循環(huán)中判斷相鄰兩個元素是否逆序,是的話將兩個元素交換,外層循環(huán)一次,就能將數(shù)組中剩下的元素中最小的元素"浮"到最前面,所以稱之為冒泡排序。

  其實冒泡排序跟選擇排序比較相像,比較次數(shù)一樣,都為nx(n+1)/2,但是冒泡排序在挑選最小值的過程中會進行額外的交換(冒泡排序在排序中只要發(fā)現(xiàn)相鄰元素的順序不對就會進行交換,與之對應的是選擇排序,只會在內(nèi)層循環(huán)比較結束之后根據(jù)情況決定是否進行交換),所以在我看來,選擇排序?qū)儆诿芭菖判虻母倪M版。

  4、Java排序算法之希爾排序

  希爾排序的誕生是由于插入排序在處理大規(guī)模數(shù)組的時候會遇到需要移動太多元素的問題。希爾排序的思想是將一個大的數(shù)組"分而治之",劃分為若干個小的數(shù)組,以gap來劃分,比如數(shù)組[1,2,3,4,5,6,7,8],如果以gap=2來劃分,可以分為[1,3,5,7]和[2,4,6,8]兩個數(shù)組(對應的`,如gap=3,則劃分的數(shù)組為:[1,4,7]、[2,5,8]、[3,6])然后分別對劃分出來的數(shù)組進行插入排序,待各個子數(shù)組排序完畢之后再減小gap值重復進行之前的步驟,直至gap=1,即對整個數(shù)組進行插入排序,此時的數(shù)組已經(jīng)基本上快排好序了,所以需要移動的元素會很小很小,解決了插入排序在處理大規(guī)模數(shù)組時較多移動次數(shù)的問題。

  具體實例請參照插入排序。

  希爾排序是插入排序的改進版,在數(shù)據(jù)量大的時候?qū)π实奶嵘龓椭艽,?shù)據(jù)量小的時候建議直接使用插入排序就好了。

  5、Java排序算法之歸并排序

  歸并排序采用的是遞歸來實現(xiàn),屬于"分而治之",將目標數(shù)組從中間一分為二,之后分別對這兩個數(shù)組進行排序,排序完畢之后再將排好序的兩個數(shù)組"歸并"到一起,歸并排序最重要的也就是這個"歸并"的過程,歸并的過程中需要額外的跟需要歸并的兩個數(shù)組長度一致的空間,比如需要規(guī)定的數(shù)組分別為:[3,6,8,11]和[1,3,12,15](雖然邏輯上被劃為為兩個數(shù)組,但實際上這些元素還是位于原來數(shù)組中的,只是通過一些index將其劃分成兩個數(shù)組,原數(shù)組為[3,6,8,11,1,3,12,15,我們設置三個指針lo,mid,high分別為0,3,7就可以實現(xiàn)邏輯上的子數(shù)組劃分)那么需要的額外數(shù)組的長度為4+4=8.歸并的過程可以簡要地概括為如下:

  1)將兩個子數(shù)組中的元素復制到新數(shù)組copiedArray中,以前面提到的例子為例,則copiedArray=[3,6,8,11,1,3,12,15];

  2)設置兩個指針分別指向原子數(shù)組中對應的第一個元素,假定這兩個指針取名為leftIdx和rightIdx,則leftIdx=0(對應copiedArray中的第一個元素[3]),rightIdx=4(對應copiedArray中的第五個元素[1]);

  3)比較leftIdx和rightIdx指向的數(shù)組元素值,選取其中較小的一個并將其值賦給原數(shù)組中對應的位置i,賦值完畢后分別對參與賦值的這兩個索引做自增1操作,如果leftIdx或rigthIdx值已經(jīng)達到對應數(shù)組的末尾,則余下只需要將剩下數(shù)組的元素按順序copy到余下的位置即可。

  下面給個歸并的具體實例:

  1.第一趟:

  2.3.輔助數(shù)組[21,28,39|35,38](數(shù)組被拆分為左右兩個子數(shù)組,以|分隔開)

  4.5.[21,,,,](第一次21與35比較,左邊子數(shù)組勝出,leftIdx=0,i=0)

  6.7.第二趟:

  8.9.輔助數(shù)組[21,28,39|35,38]

  10.11.[21,28,,,](第二次28與35比較,左邊子數(shù)組勝出,leftIdx=1,i=1)

  12.13.第三趟:[21,28,39|35,38]

  14.15.[21,28,35,,](第三次39與35比較,右邊子數(shù)組勝出,rightIdx=0,i=2)

  16.17.第四趟:[21,28,39|35,38]

  18.19.[21,28,35,38,](第四次39與38比較,右邊子數(shù)組勝出,rightIdx=1,i=3)

  20.21.第五趟:[21,28,39|35,38]

  22.23.[21,28,35,38,39](第五次時右邊子數(shù)組已復制完,無需比較leftIdx=2,i=4)

  以上便是一次歸并的過程,我們可以將整個需要排序的數(shù)組做有限次拆分(每次一分為二)直到分為長度為1的小數(shù)組為止,長度為1時數(shù)組已經(jīng)不用排序了。在這之后再逆序(由于采用遞歸)依次對這些數(shù)組進行歸并操作,直到最后一次歸并長度為n/2的子數(shù)組,歸并完成之后數(shù)組排序也完成。

  歸并排序需要的額外空間是所有排序中最多的,每次歸并需要與參與歸并的兩個數(shù)組長度之和相同個元素(為了提供輔助數(shù)組)。則可以推斷歸并排序的空間復雜度為1+2+4+…+n=nx(n+2)/4(忽略了n的奇偶性的判斷),時間復雜度比較難估,這里小弟也忘記是多少了(囧)。

  Java的五大排序算法2

  簡單選擇排序:

  (選出最小值,放在第一位,然后第一位向后推移,如此循環(huán))第一位與后面每一個逐個比較,每次都使最小的置頂,第一位向后推進(即剛選定的第一位是最小值,不再參與比較,比較次數(shù)減1)

  復雜度:所需進行記錄移動的操作次數(shù)較少0--3(n-1),無論記錄的初始排列如何,所需的關鍵字間的比較次數(shù)相同,均為n(n-1)/2,總的時間復雜度為O(n2);

  空間復雜度O(1)

  算法改進:每次對比,都是為了將最小的值放到第一位,所以可以一比到底,找出最小值,直接放到第一位,省去無意義的調(diào)換移動操作。也可以換一個方向,最后一位與前面每一個比較,每次使最大值沉底,最后一位向前推進。

  復制代碼代碼如下:

  publicstaticvoidselectSort(Date[]days){

  intmin;

  Datetemp;

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

  min=i;

  for(intj=min+1;j<days.length;j++){

  if(days[min].compare(days[j])>0){

  min=j;

  }

  }

  if(min!=i){

  temp=days[i];

  days[i]=days[min];

  days[min]=temp;

  }

  }

  }

  classDate{

  intyear,month,day;

  Date(inty,intm,intd){

  year=y;

  month=m;

  day=d;

  }

  publicintcompare(Datedate){

  returnyear>date.year?1:year<date.year?-1

  :month>date.month?1:month<date.month?-1

  :day>date.day?1:day<date.day?-1:0;

  }

  publicvoidprint(){

  System.out.println(year+""+month+""+day);

  }

  }

  簡單選擇排序(SimpleSelectionSort):

  簡單選擇排序類似于冒泡排序(BubbleSort),每次都會在剩下的元素集合中選擇出一個最值出來填充到當前位置。唯一的區(qū)別是,冒泡排序在每次發(fā)現(xiàn)比當前值小于(或大于)時,都會交換元素的位置,而簡單選擇排序是選擇剩余元素中的最值和當前位置交換數(shù)據(jù)。

  比如對于元素集合R={37,40,38,42,461,5,7,9,12}

  在第一趟排序中:37直接和5交換,形成新的序列R1={5,40,38,42,461,37,7,9,12}

  在第二趟排序中:40直接和7交換,形成新的序列R2={5,7,38,42,461,37,40,9,12}

  以此類推,直到最后一個元素(注意:在第二趟排序中,38比42小,但是他們并沒有交換數(shù)據(jù))。

  以下是簡單選擇排序的一個Java實現(xiàn)版本:

  復制代碼代碼如下:

  publicstaticvoidselectionSort(int[]data){

  if(data==null||data.length<=1)

  return;

  inti,j,value,minPos,len=data.length;

  intouter=len-1,tmp;

  for(i=0;i<outer;i++){

  value=data[i];

  minPos=-1;

  for(j=i+1;j<len;j++){

  if(data[j]<value){

  minPos=j;

  value=data[j];

  }

  }

  if(minPos!=-1){

  tmp=data[i];

  data[i]=value;

  data[minPos]=tmp;

  }

  //for(intk=0;k<len;k++){

  //System.out.print(data[k]+",");

  //}

  //System.out.println();

  }

  }

  publicstaticvoidmain(String[]args){

  int[]coll={

  37,40,38,42,461,5,7,9,12

  };

  selectionSort(coll);

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

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

  }

  }

  樹選擇排序(TreeSelectionSort)

  樹選擇排序算法相對于簡單選擇排序來說是典型的.以空間換時間的算法。其思想是對待排序的N個元素,構造出相對較小的(n+1)/2個數(shù),然后再構造出相對較小的[n+1]/4個數(shù),直到只有一個元素為止。構造成一個完全二叉樹。

  排序的時候,那個元素就是最小的,取出該最小元素,將該元素替換為"最大值",再調(diào)整完全二叉樹。

  下面是樹形選擇排序的一個Java實現(xiàn)版:

  復制代碼代碼如下:

  publicstaticvoidtreeSelectionSort(int[]data){

  if(data==null||data.length<=1)

  return;

  intlen=data.length,low=0,i,j;

  //addAuxiliarySpace

  int[]tmp=newint[2xlen-1];

  inttSize=tmp.length;

  //constructatree

  for(i=len-1,j=tmp.length-1;i>=0;i--,j--){

  tmp[j]=data[i];

  }

  for(i=tSize-1;i>0;i-=2){

  tmp[(i-1)/2]=tmp[i]>tmp[i-1]?tmp[i-1]:tmp[i];

  }

  //end

  //removetheminimumnode.

  while(low<len){

  data[low++]=tmp[0];

  for(j=tSize-1;tmp[j]!=tmp[0];j--);

  tmp[j]=Integer.MAX_VALUE;

  while(j>0){

  if(j%2==0){//如果是右節(jié)點

  tmp[(j-1)/2]=tmp[j]>tmp[j-1]?tmp[j-1]:tmp[j];

  j=(j-1)/2;

  }else{//如果是左節(jié)點

  tmp[j/2]=tmp[j]>tmp[j+1]?tmp[j+1]:tmp[j];

  j=j/2;

  }

  }

  }

  }

  在構造完全二叉樹的時候?qū)個元素的集合,需要2xN-1個輔助空間。

  復制代碼代碼如下:

  while(j>0){

  if(j%2==0){//如果是右節(jié)點

  tmp[(j-1)/2]=tmp[j]>tmp[j-1]?tmp[j-1]:tmp[j];

  j=(j-1)/2;

  }else{//如果是左節(jié)點

  tmp[j/2]=tmp[j]>tmp[j+1]?tmp[j+1]:tmp[j];

  j=j/2;

  }

  }

  則實現(xiàn)遞歸的構造新集合中的最小值。

【Java的五大排序算法】相關文章:

java的常見排序方法04-03

PHP快速排序算法解析03-30

PHP排序算法類講解03-18

教你JAVA語言快速排序的原理03-30

C語言中使用快速排序算法對元素排序的實例03-18

java通用組合算法如何實現(xiàn)03-28

C語言選擇排序算法及實例代碼11-25

C語言插入排序算法及實例代碼12-05

C語言實現(xiàn)歸并排序算法實例04-01