java中歸并排序和Master公式詳解
基本思想
歸并排序采取分治的思想進(jìn)行排序,借用一張圖片說明一下

將n個(gè)元素從中間切開,分成兩部分。(左邊可能比右邊多1個(gè)數(shù)) 將步驟1分成的兩部分,再分別進(jìn)行遞歸分解。直到所有部分的元素個(gè)數(shù)都為1。 從最底層開始逐步合并兩個(gè)排好序的數(shù)列。
優(yōu)點(diǎn)在于,分治之后,合并排序的過程時(shí)間復(fù)雜度是O(N)(只需要掃描一遍就可以將兩個(gè)有序的數(shù)組合并成一個(gè)有序數(shù)組)
實(shí)現(xiàn)
public static void MergeSort(int[] arr,int l , int r) {
if (l == r || r < 0){
return;
}
int middle = l+(r-l)/2; //取中值,可以防止達(dá)到Integer.MaxValue 溢出
MergeSort(arr,l,middle);
MergeSort(arr,middle+1,r);
sort(arr,l,middle,r);
}
/**
*
* @param arr 等待排序的數(shù)組
* @param l 左數(shù)組第一個(gè)指針
* @param middle 分割左右數(shù)組
* @param r 右數(shù)組最后一個(gè)指針
*/
private static void sort(int[] arr, int l, int middle, int r) {
int[] temp = new int[arr.length];
System.arraycopy(arr, 0, temp, 0, arr.length);
int right_first = middle+1;
int tempIndex = l;
while (l <= middle && right_first <= r){
if (temp[tempIndex] < temp[right_first]){
arr[l++] = temp[tempIndex++];
}else {
arr[l++] = temp[right_first++];
}
}
while (tempIndex <= middle){
arr[l++] = temp[tempIndex++];
}
while (right_first <= r ){
arr[l++] = temp[right_first++];
}
}
對(duì)數(shù)器驗(yàn)證
我們可以寫個(gè)對(duì)數(shù)器,使用暴力排序的方式驗(yàn)證我們的排序方法是否準(zhǔn)確
//生成1-100內(nèi)隨機(jī)數(shù)組
public static int[] getParamArrays(){
int[] result = new int[(int) (Math.random() * 100)];
//隨機(jī)生成數(shù)
for (int i = 0; i < result.length; i++) {
result[i] = (int) (Math.random() * 100);
}
return result;
}
public static void main(String[] args){
for (int i = 0; i < 1000000; i++) {
int[] nums = getParamArrays();
int[] temp = nums;
MergeSort(nums,0,nums.length-1);
Arrays.sort(temp);
//通過自定義比較次數(shù),對(duì)隨機(jī)數(shù)組進(jìn)行排序驗(yàn)證正確性
if (!nums.equals(temp)){
System.out.println("wrong");
}
}
System.out.println("end");
}
遞歸時(shí)間復(fù)雜度計(jì)算 Master 公式
形如
T(N) = a * T(N/b) + O(N^d)(其中的a、b、d都是常數(shù))
的遞歸函數(shù),可以直接通過Master公式來確定時(shí)間復(fù)雜度
如果 log(b,a) < d,復(fù)雜度為O(N^d)
如果 log(b,a) > d,復(fù)雜度為O(N^log(b,a))
如果 log(b,a) == d,復(fù)雜度為O(N^d * logN)
此公式適用于子遞歸規(guī)模相等的情況下
a表示遞歸的次數(shù)也就是生成的子問題數(shù),b表示每次遞歸是原來的1/b之一個(gè)規(guī)模,O(N^d) 表示分解和合并所要花費(fèi)的時(shí)間之和(除開遞歸的復(fù)雜度)
此處就是 T(N)= 2*T(N/2)+O(N^1) 適用于第三種情況 復(fù)雜度為 O(nlogn)
總結(jié)
到此這篇關(guān)于java中歸并排序和Master公式詳解的文章就介紹到這了,更多相關(guān)java歸并排序和Master公式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java?嵌入數(shù)據(jù)引擎從?SQLite?到?SPL詳解
這篇文章主要介紹了Java?嵌入數(shù)據(jù)引擎:從?SQLite?到?SPL,SQLite架構(gòu)簡單,其核心雖然是C語言開發(fā)的,但封裝得比較好,對(duì)外呈現(xiàn)為一個(gè)小巧的Jar包,能方便地集成在Java應(yīng)用中,本文給大家介紹的非常詳細(xì),需要的朋友參考下2022-07-07
詳解springboot項(xiàng)目docker部署實(shí)踐
這篇文章主要介紹了詳解springboot項(xiàng)目docker部署實(shí)踐,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-01-01
java 出現(xiàn)Zipexception 異常的解決辦法
這篇文章主要介紹了java 出現(xiàn)Zipexception 異常的解決辦法的相關(guān)資料,出現(xiàn) java.util.zip.ZipException: error in opening zip file 異常的原因及解決方法,需要的朋友可以參考下2017-08-08
MyBatis 實(shí)現(xiàn)批量插入和刪除中雙層循環(huán)的寫法案例
這篇文章主要介紹了MyBatis 實(shí)現(xiàn)批量插入和刪除中雙層循環(huán)的寫法案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-01-01
Java classloader和namespace詳細(xì)介紹
這篇文章主要介紹了Java classloader和namespace詳細(xì)介紹的相關(guān)資料,需要的朋友可以參考下2017-03-03
MyEclipse2017創(chuàng)建Spring項(xiàng)目的方法
這篇文章主要為大家詳細(xì)介紹了MyEclipse2017創(chuàng)建Spring項(xiàng)目的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-03-03
java數(shù)據(jù)結(jié)構(gòu)-堆實(shí)現(xiàn)優(yōu)先隊(duì)列
通常都把隊(duì)列比喻成排隊(duì)買東西,大家都很守秩序,先排隊(duì)的人就先買東西。但是優(yōu)先隊(duì)列有所不同,它不遵循先進(jìn)先出的規(guī)則,而是根據(jù)隊(duì)列中元素的優(yōu)先權(quán),優(yōu)先權(quán)最大的先被取出,這篇文章主要介紹了java數(shù)據(jù)結(jié)構(gòu)-堆實(shí)現(xiàn)優(yōu)先隊(duì)列,感興趣的朋友一起看看吧2021-08-08

