日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

【转】排序算法复习(Java实现) (二): 归并排序,堆排序,桶式排序,基数排序...

發布時間:2024/6/5 java 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【转】排序算法复习(Java实现) (二): 归并排序,堆排序,桶式排序,基数排序... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

http://www.blogjava.net/javacap/archive/2007/12/14/167618.html

六 歸并排序
算法思想是每次把待排序列分成兩部分,分別對這兩部分遞歸地用歸并排序,完成后把這兩個子部分合并成一個
序列。
歸并排序借助一個全局性臨時數組來方便對子序列的歸并,該算法核心在于歸并。?

package?algorithms;

import?java.lang.reflect.Array;

/**
?*?
@author?yovn
?*
?
*/
public?class?MergeSorter<E?extends?Comparable<E>>?extends?Sorter<E>??{

????
/*?(non-Javadoc)
?????*?@see?algorithms.Sorter#sort(E[],?int,?int)
?????
*/
????@SuppressWarnings(
"unchecked")
????@Override
????
public?void?sort(E[]?array,?int?from,?int?len)?{
????????
if(len<=1)return;
????????E[]?temporary
=(E[])Array.newInstance(array[0].getClass(),len);
????????merge_sort(array,from,from
+len-1,temporary);

????}

????
private?final?void?merge_sort(E[]?array,?int?from,?int?to,?E[]?temporary)?{
????????
if(to<=from)
????????{
????????????
return;
????????}
????????
int?middle=(from+to)/2;
????????merge_sort(array,from,middle,temporary);
????????merge_sort(array,middle
+1,to,temporary);
????????merge(array,from,to,middle,temporary);
????}

????
private?final?void?merge(E[]?array,?int?from,?int?to,?int?middle,?E[]?temporary)?{
????????
int?k=0,leftIndex=0,rightIndex=to-from;
????????System.arraycopy(array,?from,?temporary,?
0,?middle-from+1);
????????
for(int?i=0;i<to-middle;i++)
????????{
????????????temporary[to
-from-i]=array[middle+i+1];
????????}
????????
while(k<to-from+1)
????????{
????????????
if(temporary[leftIndex].compareTo(temporary[rightIndex])<0)
????????????{
????????????????array[k
+from]=temporary[leftIndex++];
????????????????
????????????}
????????????
else
????????????{
????????????????array[k
+from]=temporary[rightIndex--];
????????????}
????????????k
++;
????????}
????????
????}

}

七 堆排序
堆是一種完全二叉樹,一般使用數組來實現。
堆主要有兩種核心操作,
1)從指定節點向上調整(shiftUp)
2)從指定節點向下調整(shiftDown)
建堆,以及刪除堆定節點使用shiftDwon,而在插入節點時一般結合兩種操作一起使用。
堆排序借助最大值堆來實現,第i次從堆頂移除最大值放到數組的倒數第i個位置,然后shiftDown到倒數第i+1個位置,一共執行N此調整,即完成排序。
顯然,堆排序也是一種選擇性的排序,每次選擇第i大的元素。

package?algorithms;

/**
?*?
@author?yovn
?*
?
*/
public?class?HeapSorter<E?extends?Comparable<E>>?extends?Sorter<E>??{

????
/*?(non-Javadoc)
?????*?@see?algorithms.Sorter#sort(E[],?int,?int)
?????
*/
????@Override
????
public?void?sort(E[]?array,?int?from,?int?len)?{
????????build_heap(array,from,len);

????????
for(int?i=0;i<len;i++)
????????{
????????????
//swap?max?value?to?the?(len-i)-th?position
????????????swap(array,from,from+len-1-i);
????????????shift_down(array,from,len
-1-i,0);//always?shiftDown?from?0
????????}
????}

????
private?final?void?build_heap(E[]?array,?int?from,?int?len)?{
????????
int?pos=(len-1)/2;//we?start?from?(len-1)/2,?because?branch's?node?+1=leaf's?node,?and?all?leaf?node?is?already?a?heap
????????for(int?i=pos;i>=0;i--)
????????{
????????????shift_down(array,from,len,i);
????????}
????????
????}
????
????
private?final?void?shift_down(E[]?array,int?from,?int?len,?int?pos)
????{
????????
????????E?tmp
=array[from+pos];
????????
int?index=pos*2+1;//use?left?child
????????while(index<len)//until?no?child
????????{
????????????
if(index+1<len&&array[from+index].compareTo(array[from+index+1])<0)//right?child?is?bigger
????????????{
????????????????index
+=1;//switch?to?right?child
????????????}
????????????
if(tmp.compareTo(array[from+index])<0)
????????????{
????????????????array[from
+pos]=array[from+index];
????????????????pos
=index;
????????????????index
=pos*2+1;
????????????????
????????????}
????????????
else
????????????{
????????????????
break;
????????????}
????????????
????????}
????????array[from
+pos]=tmp;
????????????
????}

????
}

八 桶式排序
桶式排序不再是基于比較的了,它和基數排序同屬于分配類的排序,這類排序的特點是事先要知道待排序列的一些特征。
桶式排序事先要知道待排序列在一個范圍內,而且這個范圍應該不是很大的。
比如知道待排序列在[0,M)內,那么可以分配M個桶,第I個桶記錄I的出現情況,最后根據每個桶收到的位置信息把數據輸出成有序的形式。
這里我們用兩個臨時性數組,一個用于記錄位置信息,一個用于方便輸出數據成有序方式,另外我們假設數據落在0到MAX,如果所給數據不是從0開始,你可以把每個數減去最小的數。

package?algorithms;

/**
?*?
@author?yovn
?*
?
*/
public?class?BucketSorter?{

????
????
????
public?void?sort(int[]?keys,int?from,int?len,int?max)
????{
????????
int[]?temp=new?int[len];
????????
int[]?count=new?int[max];
????????
????????
????????
for(int?i=0;i<len;i++)
????????{
????????????count[keys[from
+i]]++;
????????}
????????
//calculate?position?info
????????for(int?i=1;i<max;i++)
????????{
????????????count[i]
=count[i]+count[i-1];//this?means?how?many?number?which?is?less?or?equals?than?i,thus?it?is?also?position?+?1?
????????}
????????
????????System.arraycopy(keys,?from,?temp,?
0,?len);
????????
for(int?k=len-1;k>=0;k--)//from?the?ending?to?beginning?can?keep?the?stability
????????{
????????????keys[
--count[temp[k]]]=temp[k];//?position?+1?=count
????????}
????}
????
/**
?????*?
@param?args
?????
*/
????
public?static?void?main(String[]?args)?{

????????
int[]?a={1,4,8,3,2,9,5,0,7,6,9,10,9,13,14,15,11,12,17,16};
????????BucketSorter?sorter
=new?BucketSorter();
????????sorter.sort(a,
0,a.length,20);//actually?is?18,?but?20?will?also?work
????????
????????
????????
for(int?i=0;i<a.length;i++)
????????{
????????????System.out.print(a[i]
+",");
????????}

????}

}

九 基數排序
基數排序可以說是擴展了的桶式排序,比如當待排序列在一個很大的范圍內,比如0到999999內,那么用桶式排序是很浪費空間的。而基數排序把每個排序碼拆成由d個排序碼,比如任何一個6位數(不滿六位前面補0)拆成6個排序碼,分別是個位的,十位的,百位的。。。。
排序時,分6次完成,每次按第i個排序碼來排。
一般有兩種方式:
1) 高位優先(MSD): 從高位到低位依次對序列排序
2)低位優先(LSD): 從低位到高位依次對序列排序
計算機一般采用低位優先法(人類一般使用高位優先),但是采用低位優先時要確保排序算法的穩定性。
基數排序借助桶式排序,每次按第N位排序時,采用桶式排序。對于如何安排每次落入同一個桶中的數據有兩種安排方法:
1)順序存儲:每次使用桶式排序,放入r個桶中,,相同時增加計數。
2)鏈式存儲:每個桶通過一個靜態隊列來跟蹤。

package?algorithms;

import?java.util.Arrays;


/**
?*?
@author?yovn
?*
?
*/
public?class?RadixSorter?{
????
????
public?static?boolean?USE_LINK=true;
????
????
/**
?????*?
?????*?
@param?keys
?????*?
@param?from
?????*?
@param?len
?????*?
@param?radix??key's?radix
?????*?
@param?d??????how?many?sub?keys?should?one?key?divide?to
?????
*/
????
public?void?sort(int[]?keys,int?from?,int?len,int?radix,?int?d)
????{
????????
if(USE_LINK)
????????{
????????????link_radix_sort(keys,from,len,radix,d);
????????}
????????
else
????????{
????????????array_radix_sort(keys,from,len,radix,d);
????????}
????????
????}
????
????
????
private?final?void?array_radix_sort(int[]?keys,?int?from,?int?len,?int?radix,
????????????
int?d)?
????{
????????
int[]?temporary=new?int[len];
????????
int[]?count=new?int[radix];
????????
int?R=1;
????????
????????
for(int?i=0;i<d;i++)
????????{
????????????System.arraycopy(keys,?from,?temporary,?
0,?len);
????????????Arrays.fill(count,?
0);
????????????
for(int?k=0;k<len;k++)
????????????{
????????????????
int?subkey=(temporary[k]/R)%radix;
????????????????count[subkey]
++;
????????????}
????????????
for(int?j=1;j<radix;j++)
????????????{
????????????????count[j]
=count[j]+count[j-1];
????????????}
????????????
for(int?m=len-1;m>=0;m--)
????????????{
????????????????
int?subkey=(temporary[m]/R)%radix;
????????????????
--count[subkey];
????????????????keys[from
+count[subkey]]=temporary[m];
????????????}
????????????R
*=radix;
????????}
???????????
????}


????
private?static?class?LinkQueue
????{
????????
int?head=-1;
????????
int?tail=-1;
????}
????
private?final?void?link_radix_sort(int[]?keys,?int?from,?int?len,?int?radix,?int?d)?{
????????
????????
int[]?nexts=new?int[len];
????????
????????LinkQueue[]?queues
=new?LinkQueue[radix];
????????
for(int?i=0;i<radix;i++)
????????{
????????????queues[i]
=new?LinkQueue();
????????}
????????
for(int?i=0;i<len-1;i++)
????????{
????????????nexts[i]
=i+1;
????????}
????????nexts[len
-1]=-1;
????????
????????
int?first=0;
????????
for(int?i=0;i<d;i++)
????????{
????????????link_radix_sort_distribute(keys,from,len,radix,i,nexts,queues,first);
????????????first
=link_radix_sort_collect(keys,from,len,radix,i,nexts,queues);
????????}
????????
int[]?tmps=new?int[len];
????????
int?k=0;
????????
while(first!=-1)
????????{
????????
????????????tmps[k
++]=keys[from+first];
????????????first
=nexts[first];
????????}
????????System.arraycopy(tmps,?
0,?keys,?from,?len);
????????
????????
????}
????
private?final?void?link_radix_sort_distribute(int[]?keys,?int?from,?int?len,
????????????
int?radix,?int?d,?int[]?nexts,?LinkQueue[]?queues,int?first)?{
????????
????????
for(int?i=0;i<radix;i++)queues[i].head=queues[i].tail=-1;
????????
while(first!=-1)
????????{
????????????
int?val=keys[from+first];
????????????
for(int?j=0;j<d;j++)val/=radix;
????????????val
=val%radix;
????????????
if(queues[val].head==-1)
????????????{
????????????????queues[val].head
=first;
????????????}
????????????
else?
????????????{
????????????????nexts[queues[val].tail]
=first;
????????????????
????????????}
????????????queues[val].tail
=first;
????????????first
=nexts[first];
????????}
????????
????}
????
private?int?link_radix_sort_collect(int[]?keys,?int?from,?int?len,
????????????
int?radix,?int?d,?int[]?nexts,?LinkQueue[]?queues)?{
????????
int?first=0;
????????
int?last=0;
????????
int?fromQueue=0;
????????
for(;(fromQueue<radix-1)&&(queues[fromQueue].head==-1);fromQueue++);
????????first
=queues[fromQueue].head;
????????last
=queues[fromQueue].tail;
????????
????????
while(fromQueue<radix-1&&queues[fromQueue].head!=-1)
????????{
????????????fromQueue
+=1;
????????????
for(;(fromQueue<radix-1)&&(queues[fromQueue].head==-1);fromQueue++);
????????????
????????????nexts[last]
=queues[fromQueue].head;
????????????last
=queues[fromQueue].tail;
????????????
????????}
????????
if(last!=-1)nexts[last]=-1;
????????
return?first;
????}
????
????
/**
?????*?
@param?args
?????
*/
????
public?static?void?main(String[]?args)?{
????????
int[]?a={1,4,8,3,2,9,5,0,7,6,9,10,9,135,14,15,11,222222222,1111111111,12,17,45,16};
????????USE_LINK
=true;
????????RadixSorter?sorter
=new?RadixSorter();
????????sorter.sort(a,
0,a.length,10,10);
????????
for(int?i=0;i<a.length;i++)
????????{
????????????System.out.print(a[i]
+",");
????????}


????}

}?


?

?

?

轉載于:https://www.cnblogs.com/fzzl/archive/2010/08/14/1799406.html

總結

以上是生活随笔為你收集整理的【转】排序算法复习(Java实现) (二): 归并排序,堆排序,桶式排序,基数排序...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。