圖解Java經(jīng)典算法歸并排序的原理與實(shí)現(xiàn)
歸并排序
歸并排序主要分成兩部分實(shí)現(xiàn),分、合兩部分,分是把數(shù)組分成兩半,再遞歸的對(duì)子數(shù)組進(jìn)行 分 操作,直到分成一個(gè)個(gè)單獨(dú)的數(shù)。合是把兩個(gè)數(shù)組合并為有序數(shù)組,在對(duì)有序數(shù)組進(jìn)行合并,直到全部子數(shù)組合并為一個(gè)完整的數(shù)組。
算法原理
- 申請(qǐng)空間,使其大小為兩個(gè)已經(jīng)排序序列之和,該空間用來(lái)存放合并后的序列
- 設(shè)定兩個(gè)指針,最初位置分別為兩個(gè)已經(jīng)排序序列的起始位置
- 比較兩個(gè)指針?biāo)赶虻脑兀x擇相對(duì)小的元素放入到合并空間,并移動(dòng)指針到下一位置
- 重復(fù)步驟c直到某一指針超出序列尾
- 將另一序列剩下的所有元素直接復(fù)制到合并序列尾
動(dòng)圖演示

代碼實(shí)現(xiàn)
public class MergeSort {
//歸并所需的輔助數(shù)組
private static Comparable[] assist;
//比較 v 是否小于 w
public static boolean less(Comparable v,Comparable w){
return v.compareTo(w) < 0;
}
//數(shù)組元素交換位置
private static void swap(Comparable[] a,int i,int j){
Comparable temp;
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
//排序
public static void sort(Comparable[] a){
//初始化輔助數(shù)組
assist = new Comparable[a.length];
int l = 0;
int h = a.length - 1;
sort(a,l,h);
}
private static void sort(Comparable[] a,int l,int h){
if (h <= l){
return;
}
//分組
int mid = l +(h - l) / 2;
//分別對(duì)每組數(shù)據(jù)排序
sort(a,l,mid);
sort(a,mid + 1,h);
//對(duì)數(shù)組進(jìn)行歸并
merge(a,l,mid,h);
}
//對(duì)數(shù)組進(jìn)行歸并
private static void merge(Comparable[] a,int l,int mid,int h){
//定義三個(gè)指針
int i = l;
int p1 = l;
int p2 = mid + 1;
//遍歷,移動(dòng)p1,p2指針,比較兩處索引的值,小的放到輔助數(shù)組的對(duì)應(yīng)索引處
while (p1 <= mid && p2 <=h){
if (less(a[p1],a[p2])){
assist[i++] = a[p1++];
}else {
assist[i++] = a[p2++];
}
}
//遍歷數(shù)組,如果p1的指針沒(méi)有走完,則順序移動(dòng)p1指針,把對(duì)應(yīng)的元素放到輔助數(shù)組的對(duì)應(yīng)索引處
while (p1 <= mid){
assist[i++] = a[p1++];
}
//遍歷數(shù)組,如果p2的指針沒(méi)有走完,則順序移動(dòng)p2指針,把對(duì)應(yīng)的元素放到輔助數(shù)組的對(duì)應(yīng)索引處
while (p2 <= h){
assist[i++] = a[p2++];
}
//把輔助數(shù)組中的元素拷貝到原數(shù)組中
for (int j = l; j <= h; j++) {
a[j] = assist[j];
}
}
}public class MergeSortTest {
public static void main(String[] args) {
Integer[] arr = {5,6,3,1,8,7,2,4};
MergeSort.sort(arr);
System.out.println(Arrays.toString(arr));
}
}
//排序前:{5,6,3,1,8,7,2,4}
//排序后:{1,2,3,4,5,6,7,8}
復(fù)雜度
- 時(shí)間復(fù)雜度:O(nlogn)
- 空間復(fù)雜度:O(n)
到此這篇關(guān)于圖解Java經(jīng)典算法歸并排序的原理與實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Java歸并排序內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot獲取配置文件的簡(jiǎn)單實(shí)現(xiàn)方法
這篇文章主要給大家介紹了關(guān)于SpringBoot如何獲取配置文件的簡(jiǎn)單實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Spring Boot具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05
SpringMVC 實(shí)現(xiàn)用戶(hù)登錄實(shí)例代碼
這篇文章主要介紹了SpringMVC 實(shí)現(xiàn)用戶(hù)登錄實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下2017-02-02
MyBatis 多個(gè)條件使用Map傳遞參數(shù)進(jìn)行批量刪除方式
這篇文章主要介紹了MyBatis 多個(gè)條件使用Map傳遞參數(shù)進(jìn)行批量刪除方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12
Spring MVC項(xiàng)目開(kāi)發(fā)踩過(guò)的一些bug
這篇文章主要給大家介紹了關(guān)于Spring MVC項(xiàng)目開(kāi)發(fā)踩過(guò)的一些bug,文中通過(guò)圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11
springboot Rabbit MQ topic 配置文件綁定隊(duì)列和交換機(jī)的
本文詳細(xì)講解了在SpringBoot中使用RabbitMQ進(jìn)行隊(duì)列與交換機(jī)的綁定方法,包括創(chuàng)建交換機(jī)、隊(duì)列和綁定它們的步驟,以及如何發(fā)送和接收消息,適用于開(kāi)發(fā)高并發(fā)系統(tǒng),如秒殺系統(tǒng)等2024-09-09
java算法Leecode刷題統(tǒng)計(jì)有序矩陣中的負(fù)數(shù)
這篇文章主要為大家介紹了java算法Leecode刷題統(tǒng)計(jì)有序矩陣中的負(fù)數(shù)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10
Java中FileWriter類(lèi)的簡(jiǎn)介說(shuō)明
這篇文章主要介紹了Java中FileWriter類(lèi)的簡(jiǎn)介說(shuō)明,FileWriter類(lèi)提供了多種寫(xiě)入字符的方法,包括寫(xiě)入單個(gè)字符、寫(xiě)入字符數(shù)組和寫(xiě)入字符串等,它還提供了一些其他的方法,如刷新緩沖區(qū)、關(guān)閉文件等,需要的朋友可以參考下2023-10-10
簡(jiǎn)單了解Thymeleaf語(yǔ)法 數(shù)據(jù)延遲加載使用實(shí)例
這篇文章主要介紹了簡(jiǎn)單了解Thymeleaf語(yǔ)法 數(shù)據(jù)延遲加載使用實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2010-05-05
Java CyclicBarrier源碼層分析與應(yīng)用
這篇文章主要介紹了Java CyclicBarrier的源碼層分析與應(yīng)用,CyclicBarrier也叫同步屏障,可以讓一組線(xiàn)程達(dá)到一個(gè)屏障時(shí)被阻塞,直到最后一個(gè)線(xiàn)程達(dá)到屏障,感興趣的的朋友可以參考下2023-12-12

