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

歡迎訪問 生活随笔!

生活随笔

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

java

java常见的算法_Java常用算法总结(转)

發布時間:2025/3/15 java 14 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java常见的算法_Java常用算法总结(转) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

交換排序

冒泡排序

將最后一個元素與倒數第二個元素對比,如果最后一個元素比倒數第二個小,則交換兩個元素的位置,再用倒數第二個元素與倒數第三個元數對比,直到比到第一個元素,這樣經過第一趟排序后得到第一個最小元素。如此反復幾過N(N=length-1)次后可得到排序結果。

Java代碼?

packagesort;

importjava.util.Comparator;

/**

* 冒泡排序算法

* @author jzj

* @date 2009-12-9

*

* @param

*/

publicclassBubbleSort>extendsSort {

/**

* 排序算法的實現,對數組中指定的元素進行排序

* @param array 待排序的數組

* @param from 從哪里開始排序

* @param end 排到哪里

* @param c 比較器

*/

publicvoidsort(E[] array,intfrom,intend, Comparator c) {

//需array.length - 1輪比較

for(intk =1; k < end - from +1; k++) {

//每輪循環中從最后一個元素開始向前起泡,直到i=k止,即i等于輪次止

for(inti = end - from; i >= k; i--) {

//按照一種規則(后面元素不能小于前面元素)排序

if(c.compare(array[i], array[i -1]) <0) {

//如果后面元素小于了(當然是大于還是小于要看比較器實現了)前面的元素,則前后交換

swap(array, i, i - 1);

}

}

}

}

/**

* 測試

* @param args

*/

publicstaticvoidmain(String[] args) {

Integer[] intgArr = { 7,2,4,3,12,1,9,6,8,5,11,10};

BubbleSort sort = newBubbleSort();

BubbleSort.testSort(sort, intgArr);

BubbleSort.testSort(sort, null);

}

}

快速排序

快速排序采用了分治法的思想,把大的問題分解為同類型的小問題。 一般分如下步驟: 1)選擇一個中樞元素(有很多選法,我的實現里使用第一個元素為中樞的簡單方法) 2)以該中樞元素為基準點,將小于中樞的元素放在中樞后集合的前部分,比它大的在集合后部分,待集合基本排序完成后(此時前部分元素小于后部分元素),把中樞元素放在合適的位置。 3)根據中樞元素最后確定的位置,把數組分成三部分,左邊的,右邊的,樞紐元素自己,對左邊的,右邊的分別遞歸調用快速排序算法即可。

這里的重點與難點在于第二步,實現的方式有很多種,我這里實現了三種。 第一種實現(partition1方法): 以第一個元素為中樞元素,在中樞元素后面集合中從前往后尋找第一個比中樞元素小的元素,并與第一個元素交換,然后從剩余的元素中尋找第二個比中樞元素小的 元素,并與第二位元素交換,這樣直到所有小于中樞元素找完為止,并記下最后一次放置小于中樞的元素位置minIndex(即小于中樞與大于中樞的分界), 并將中樞元素與minIndex位置元素互換,然后對中樞元素兩邊的序列進行同樣的操作。 此種實現最為簡潔,處理過程中不需要把中樞元素移來移去,只是在其它元素完成基本排序后(前部分小于后部分元素)再把中樞元素放置到適當的位置

第二種實現(partition2方法): 以第一個元素為中樞元素,剛開始時使用低指針指向中樞元素。當中樞元素在低指針位置時,此時我們判斷高指針指向的元素是否小于中樞元素,如果大于中樞元素 則高指針繼續向頭移動,如果小于則與中樞元素交換,此時中樞元素被移到了高指針位置;當中樞元素在高指針位置時,我們此時判斷低指針指向的元素是否大于中 樞元素,如果小于中樞元素則低指針繼續向尾移動,如果大于則與中樞元素交換,此時中樞元素又回到了低指針位置;這時是拿高還是低指針所指向的元素與中樞比 較時根據前面邏輯來處理,直到高低指針指向同一位置則完成一輪排序,然后再對中樞元素兩邊的序列進行同樣的操作直到排序完成 此種實現邏輯比較好理解,中樞元素的永遠在低指針或指針所指向的位置,每次找到需處理的元 素后,要與中樞交換,中樞就像皮球一樣從這里踢到那里,又從那里踢到這里。但此種實現會頻繁地交換中樞元素,性能可能不如第一種

第三種實現(partition3方法): 此種方式與前兩種方式不太一樣,同時移動高低指針,低指針向尾找出大于等于中樞的元素,而高向頭找出小于中樞的元素,待兩者都找出后交換高低指針所指向的 元素,直到高低指針指向同一位置止,然后比較中樞與高低指針所指向的元素大小,如果中樞元素大,則直接與高低指針元素交換,如果中樞元素小于等于高低指針 元素,則中樞元素與高低指針前一元素交換,完成一輪比較,然后再對中樞元素兩邊的序列進行同樣的操作直到排序完成

此種方式有點難度,在移動元素時要注意的是:與中樞相等的元素也要向集合后部移動,不然的話如[3,3,0,3,3]第一輪排序結果不準確,雖然最后結果 正確。當中樞后面的元素集合移動完成后,還得要把中樞元素放置在集合中的合適位置,這就需要找準集合中前部分與后部分的邊界,最后只能把中樞元素與最后一 個小于中樞的元素進位置互換。但此種實現方式與第一種有點像,也不需要把中樞元素調來調去的,而是待后面集合排序完成后將中樞放入適當位置

Java代碼?

packagesort;

importjava.util.Arrays;

importjava.util.Comparator;

/**

* 快速排序算法

* @author jzj

* @date 2009-12-9

*

* @param

*/

publicclassQuickSort>extendsSort {

/**

* 排序算法的實現,對數組中指定的元素進行排序

* @param array 待排序的數組

* @param from 從哪里開始排序

* @param end 排到哪里

* @param c 比較器

*/

publicvoidsort(E[] array,intfrom,intend, Comparator c) {

quickSort(array, from, end, c);

}

/**

* 遞歸快速排序實現

* @param array 待排序數組

* @param low 低指針

* @param high 高指針

* @param c 比較器

*/

privatevoidquickSort(E[] array,intlow,inthigh, Comparator c) {

/*

* 如果分區中的低指針小于高指針時循環;如果low=higth說明數組只有一個元素,無需再處理;

* 如果low > higth,則說明上次樞紐元素的位置pivot就是low或者是higth,此種情況

* 下分區不存,也不需處理

*/

if(low < high) {

//對分區進行排序整理

intpivot = partition1(array, low, high, c);

/*

* 以pivot為邊界,把數組分成三部分[low, pivot - 1]、[pivot]、[pivot + 1, high]

* 其中[pivot]為樞紐元素,不需處理,再對[low, pivot - 1]與[pivot + 1, high]

* 各自進行分區排序整理與進一步分區

*/

quickSort(array, low, pivot - 1, c);

quickSort(array, pivot + 1, high, c);

}

}

/**

* 實現一

*

* @param array 待排序數組

* @param low 低指針

* @param high 高指針

* @param c 比較器

* @return int 調整后中樞位置

*/

privateintpartition1(E[] array,intlow,inthigh, Comparator c) {

E pivotElem = array[low];//以第一個元素為中樞元素

//從前向后依次指向比中樞元素小的元素,剛開始時指向中樞,也是小于與大小中樞的元素的分界點

intborder = low;

/*

* 在中樞元素后面的元素中查找小于中樞元素的所有元素,并依次從第二個位置從前往后存放

* 注,這里最好使用i來移動,如果直接移動low的話,最后不知道數組的邊界了,但后面需要

* 知道數組的邊界

*/

for(inti = low +1; i <= high; i++) {

//如果找到一個比中樞元素小的元素

if(c.compare(array[i], pivotElem) <0) {

swap(array, ++border, i);//border前移,表示有小于中樞元素的元素

}

}

/*

* 如果border沒有移動時說明說明后面的元素都比中樞元素要大,border與low相等,此時是

* 同一位置交換,是否交換都沒關系;當border移到了high時說明所有元素都小于中樞元素,此

* 時將中樞元素與最后一個元素交換即可,即low與high進行交換,大的中樞元素移到了 序列最

* 后;如果 low

* 中樞元素,此時中樞元素與前部分數組中最后一個小于它的元素交換位置,使得中樞元素放置在

* 正確的位置

*/

swap(array, border, low);

returnborder;

}

/**

* 實現二

*

* @param array 待排序數組

* @param low 待排序區低指針

* @param high 待排序區高指針

* @param c 比較器

* @return int 調整后中樞位置

*/

privateintpartition2(E[] array,intlow,inthigh, Comparator c) {

intpivot = low;//中樞元素位置,我們以第一個元素為中樞元素

//退出條件這里只可能是 low = high

while(true) {

if(pivot != high) {//如果中樞元素在低指針位置時,我們移動高指針

//如果高指針元素小于中樞元素時,則與中樞元素交換

if(c.compare(array[high], array[pivot]) <0) {

swap(array, high, pivot);

//交換后中樞元素在高指針位置了

pivot = high;

} else{//如果未找到小于中樞元素,則高指針前移繼續找

high--;

}

} else{//否則中樞元素在高指針位置

//如果低指針元素大于中樞元素時,則與中樞元素交換

if(c.compare(array[low], array[pivot]) >0) {

swap(array, low, pivot);

//交換后中樞元素在低指針位置了

pivot = low;

} else{//如果未找到大于中樞元素,則低指針后移繼續找

low++;

}

}

if(low == high) {

break;

}

}

//返回中樞元素所在位置,以便下次分區

returnpivot;

}

/**

* 實現三

*

* @param array 待排序數組

* @param low 待排序區低指針

* @param high 待排序區高指針

* @param c 比較器

* @return int 調整后中樞位置

*/

privateintpartition3(E[] array,intlow,inthigh, Comparator c) {

intpivot = low;//中樞元素位置,我們以第一個元素為中樞元素

low++;

//----調整高低指針所指向的元素順序,把小于中樞元素的移到前部分,大于中樞元素的移到后面部分

//退出條件這里只可能是 low = high

while(true) {

//如果高指針未超出低指針

while(low < high) {

//如果低指針指向的元素大于或等于中樞元素時表示找到了,退出,注:等于時也要后移

if(c.compare(array[low], array[pivot]) >=0) {

break;

} else{//如果低指針指向的元素小于中樞元素時繼續找

low++;

}

}

while(high > low) {

//如果高指針指向的元素小于中樞元素時表示找到,退出

if(c.compare(array[high], array[pivot]) <0) {

break;

} else{//如果高指針指向的元素大于中樞元素時繼續找

high--;

}

}

//退出上面循環時 low = high

if(low == high) {

break;

}

swap(array, low, high);

}

//----高低指針所指向的元素排序完成后,還得要把中樞元素放到適當的位置

if(c.compare(array[pivot], array[low]) >0) {

//如果退出循環時中樞元素大于了低指針或高指針元素時,中樞元素需與low元素交換

swap(array, low, pivot);

pivot = low;

} elseif(c.compare(array[pivot], array[low]) <=0) {

swap(array, low - 1, pivot);

pivot = low - 1;

}

//返回中樞元素所在位置,以便下次分區

returnpivot;

}

/**

* 測試

* @param args

*/

publicstaticvoidmain(String[] args) {

Integer[] intgArr = { 3,1,1,1,1,1,1};

QuickSort sort = newQuickSort();

QuickSort.testSort(sort, intgArr);

QuickSort.testSort(sort, null);

}

}

歸并排序

Java代碼?

packagesort;

importjava.lang.reflect.Array;

importjava.util.Comparator;

/**

* 歸并排序算法

* @author jzj

* @date 2009-12-11

*

* @param

*/

publicclassMergeSort>extendsSort {

/**

* 排序算法的實現,對數組中指定的元素進行排序

* @param array 待排序的數組

* @param from 從哪里開始排序

* @param end 排到哪里

* @param c 比較器

*/

publicvoidsort(E[] arr,intfrom,intend, Comparator c) {

partition(arr, from, end, c);

}

/**

* 遞歸劃分數組

* @param arr

* @param from

* @param end

* @param c void

*/

privatevoidpartition(E[] arr,intfrom,intend, Comparator c) {

//劃分到數組只有一個元素時才不進行再劃分

if(from < end) {

//從中間劃分成兩個數組

intmid = (from + end) /2;

partition(arr, from, mid, c);

partition(arr, mid + 1, end, c);

//合并劃分后的兩個數組

merge(arr, from, end, mid, c);

}

}

/**

* 數組合并,合并過程中對兩部分數組進行排序

* 前后兩部分數組里是有序的

* @param arr

* @param from

* @param end

* @param mid

* @param c void

*/

privatevoidmerge(E[] arr,intfrom,intend,intmid, Comparator c) {

E[] tmpArr = (E[]) Array.newInstance(arr[0].getClass(), end - from +1);

inttmpArrIndex =0;//指向臨時數組

intpart1ArrIndex = from;//指向第一部分數組

intpart2ArrIndex = mid +1;//指向第二部分數組

//由于兩部分數組里是有序的,所以每部分可以從第一個元素依次取到最后一個元素,再對兩部分

//取出的元素進行比較。只要某部分數組元素取完后,退出循環

while((part1ArrIndex <= mid) && (part2ArrIndex <= end)) {

//從兩部分數組里各取一個進行比較,取最小一個并放入臨時數組中

if(c.compare(arr[part1ArrIndex], arr[part2ArrIndex]) <0) {

//如果第一部分數組元素小,則將第一部分數組元素放入臨時數組中,并且臨時數組指針

//tmpArrIndex下移一個以做好下次存儲位置準備,前部分數組指針part1ArrIndex

//也要下移一個以便下次取出下一個元素與后部分數組元素比較

tmpArr[tmpArrIndex++] = arr[part1ArrIndex++];

} else{

//如果第二部分數組元素小,則將第二部分數組元素放入臨時數組中

tmpArr[tmpArrIndex++] = arr[part2ArrIndex++];

}

}

//由于退出循環后,兩部分數組中可能有一個數組元素還未處理完,所以需要額外的處理,當然不可

//能兩部分數組都有未處理完的元素,所以下面兩個循環最多只有一個會執行,并且都是大于已放入

//臨時數組中的元素

while(part1ArrIndex <= mid) {

tmpArr[tmpArrIndex++] = arr[part1ArrIndex++];

}

while(part2ArrIndex <= end) {

tmpArr[tmpArrIndex++] = arr[part2ArrIndex++];

}

//最后把臨時數組拷貝到源數組相同的位置

System.arraycopy(tmpArr, 0, arr, from, end - from +1);

}

/**

* 測試

* @param args

*/

publicstaticvoidmain(String[] args) {

Integer[] intgArr = { 5,9,1,4,1,2,6,3,8,0,7};

MergeSort insertSort = newMergeSort();

Sort.testSort(insertSort, intgArr);

Sort.testSort(insertSort, null);

}

}

基數排序

基數排序的主要思路是,將所有待比較數值(注意,必須是正整數)統一為同樣的數位長度,數位較短的數前面補零. 然后, 從最低位開始, 依次進行一次穩定排序.這樣從最低位排序一直到最高位排序完成以后, 數列就變成一個有序序列.

它的理論比較容易理解,但實現卻有一點繞。

Java代碼?

packagesort;

importjava.util.Arrays;

publicclassRadixSort {

/**

* 取數x上的第d位數字

* @param x 數

* @param d 第幾位,從低位到高位

* @return

*/

publicintdigit(longx,longd) {

longpow =1;

while(--d >0) {

pow *= 10;

}

return(int) (x / pow %10);

}

/**

* 基數排序實現,以升序排序(下面程序中的位記錄器count中,從第0個元素到第9個元素依次用來

* 記錄當前比較位是0的有多少個..是9的有多少個數,而降序時則從第0個元素到第9個元素依次用來

* 記錄當前比較位是9的有多少個..是0的有多少個數)

* @param arr 待排序數組

* @param digit 數組中最大數的位數

* @return

*/

publiclong[] radixSortAsc(long[] arr) {

//從低位往高位循環

for(intd =1; d <= getMax(arr); d++) {

//臨時數組,用來存放排序過程中的數據

long[] tmpArray =newlong[arr.length];

//位記數器,從第0個元素到第9個元素依次用來記錄當前比較位是0的有多少個..是9的有多少個數

int[] count =newint[10];

//開始統計0有多少個,并存儲在第0位,再統計1有多少個,并存儲在第1位..依次統計到9有多少個

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

count[digit(arr[i], d)] += 1;

}

/*

* 比如某次經過上面統計后結果為:[0, 2, 3, 3, 0, 0, 0, 0, 0, 0]則經過下面計算后 結果為:

* [0, 2, 5, 8, 8, 8, 8, 8, 8, 8]但實質上只有如下[0, 2, 5, 8, 0, 0, 0, 0, 0, 0]中

* 非零數才用到,因為其他位不存在,它們分別表示如下:2表示比較位為1的元素可以存放在索引為1、0的

* 位置,5表示比較位為2的元素可以存放在4、3、2三個(5-2=3)位置,8表示比較位為3的元素可以存放在

* 7、6、5三個(8-5=3)位置

*/

for(inti =1; i <10; i++) {

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

}

/*

* 注,這里只能從數組后往前循環,因為排序時還需保持以前的已排序好的 順序,不應該打

* 亂原來已排好的序,如果從前往后處理,則會把原來在前面會擺到后面去,因為在處理某個

* 元素的位置時,位記數器是從大到到小(count[digit(arr[i], d)]--)的方式來處

* 理的,即先存放索引大的元素,再存放索引小的元素,所以需從最后一個元素開始處理。

* 如有這樣的一個序列[212,213,312],如果按照從第一個元素開始循環的話,經過第一輪

* 后(個位)排序后,得到這樣一個序列[312,212,213],第一次好像沒什么問題,但問題會

* 從第二輪開始出現,第二輪排序后,會得到[213,212,312],這樣個位為3的元素本應該

* 放在最后,但經過第二輪后卻排在了前面了,所以出現了問題

*/

for(inti = arr.length -1; i >=0; i--) {//只能從最后一個元素往前處理

//for (int i = 0; i < arr.length; i++) {//不能從第一個元素開始循環

tmpArray[count[digit(arr[i], d)] - 1] = arr[i];

count[digit(arr[i], d)]--;

}

System.arraycopy(tmpArray, 0, arr,0, tmpArray.length);

}

returnarr;

}

/**

* 基數排序實現,以降序排序(下面程序中的位記錄器count中,從第0個元素到第9個元素依次用來

* 記錄當前比較位是0的有多少個..是9的有多少個數,而降序時則從第0個元素到第9個元素依次用來

* 記錄當前比較位是9的有多少個..是0的有多少個數)

* @param arr 待排序數組

* @return

*/

publiclong[] radixSortDesc(long[] arr) {

for(intd =1; d <= getMax(arr); d++) {

long[] tmpArray =newlong[arr.length];

//位記數器,從第0個元素到第9個元素依次用來記錄當前比較位是9的有多少個..是0的有多少個數

int[] count =newint[10];

//開始統計0有多少個,并存儲在第9位,再統計1有多少個,并存儲在第8位..依次統計

//到9有多少個,并存儲在第0位

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

count[9- digit(arr[i], d)] +=1;

}

for(inti =1; i <10; i++) {

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

}

for(inti = arr.length -1; i >=0; i--) {

tmpArray[count[9- digit(arr[i], d)] -1] = arr[i];

count[9- digit(arr[i], d)]--;

}

System.arraycopy(tmpArray, 0, arr,0, tmpArray.length);

}

returnarr;

}

privateintgetMax(long[] array) {

intmaxlIndex =0;

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

if(array[j] > array[maxlIndex]) {

maxlIndex = j;

}

}

returnString.valueOf(array[maxlIndex]).length();

}

publicstaticvoidmain(String[] args) {

long[] ary =newlong[] {123,321,132,212,213,312,21,223};

RadixSort rs = newRadixSort();

System.out.println("升 - "+ Arrays.toString(rs.radixSortAsc(ary)));

ary = newlong[] {123,321,132,212,213,312,21,223};

System.out.println("降 - "+ Arrays.toString(rs.radixSortDesc(ary)));

}

}

時間復雜度與空間復雜度對比表

原文:http://jiangzhengjun.iteye.com/blog/547735

總結

以上是生活随笔為你收集整理的java常见的算法_Java常用算法总结(转)的全部內容,希望文章能夠幫你解決所遇到的問題。

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