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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

归并排序java(内附超详解图文讲解)

發(fā)布時(shí)間:2023/12/9 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 归并排序java(内附超详解图文讲解) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

目錄

歸并排序介紹:

歸并排序圖解:

示意圖1

示意圖2

歸并排序詳細(xì)步驟:

1.組合

2.分組

完整代碼



歸并排序介紹:


歸并排序(MERGE-SORT)是利用歸并的思想實(shí)現(xiàn)的排序方法,該算法采用經(jīng)典的分治(divide- and-conquer)策略(分治法將問(wèn)題分(divide)成一些小的問(wèn)題然后遞歸求解,而治(conquer)的階段則將分的階段得到的各答案"修補(bǔ)"在一起,即分而治之)。

歸并排序圖解:

示意圖1


歸并排序思想示意圖1-基本思想:

示意圖2

歸并排序思想示意圖2-合并相鄰有序子序列:
再來(lái)看看治階段,我們需要將兩個(gè)已經(jīng)有序的子序列合并成一個(gè)有序序列,比如上圖中的最后- -次合并,要將[4,5,7,8]和[1,2,3,6]兩個(gè)已經(jīng)有序的子序列,合并為最終序列[1,2,3,4,5,6,7,8],來(lái)看下實(shí)現(xiàn)步驟:

歸并排序詳細(xì)步驟:

歸并排序的應(yīng)用實(shí)例:
給你一個(gè)數(shù)組,? arr= Array(8, 4,5,7, 1,3,6,2),請(qǐng)使用歸并排序完成排序。

為了便于大家理解 我把步驟分開:

先把最難的組合部分寫完

1.組合

1.我們先寫黑框的代碼,也就是數(shù)組已經(jīng)成為(4, 5,7,8, 1,2,3,6) 我們?nèi)绾伟阉铣? 2 3 4 5 6 7 8

可以看一下示意圖2

package suanfa;import java.util.Arrays; import java.util.Scanner;public class xishuarr {public static void main(String[] args) {int arr[]= {8,4,5,7,1,3,6,2};//假設(shè)已經(jīng)到最后一步int arrys[]= {4 ,5 ,7 ,8,1 ,2, 3, 6};int[] add=new int[8];//第一個(gè)參數(shù)表示傳入數(shù)組{4 ,5 ,7 ,8,1 ,2, 3, 6}//第二個(gè)參數(shù)表示這個(gè)數(shù)組的第一個(gè)位置 即是0//第三個(gè)參數(shù)表示這個(gè)數(shù)組的中間位置 (0+7)/2=3//第四個(gè)參數(shù) 存放臨時(shí)數(shù)組的merge(arrys,0,3,7,add);}/*** * @param arr 排序的原始數(shù)組* @param left 左邊有序序列的初始索引* @param mid 中間索引* @param right 右邊索引* @param temp 做中轉(zhuǎn)的數(shù)組*///4 5 7 8 1 2 3 6public static void merge(int[] arr,int left,int mid,int right,int[] temp) {int i=left; //初始i,左邊有序序列的初始索引int j=mid+1; //初始j,右邊有序序列的初始索引int t=0; //指向temp數(shù)組的當(dāng)前索引//1.//先把左右兩邊(有序)的數(shù)據(jù)按照規(guī)則填充到temp數(shù)組//直到左右兩邊的有序序列,有一邊處理完畢為止while(i<=mid&&j<=right) {if(arr[i]<arr[j]) {temp[t]=arr[i++];/*** 這里我們這里是:temp[t]=arr[i++];* 如果不好理解,你可以寫成這樣:* temp[t]=arr[i];i++;*/}else {temp[t]=arr[j++];}//因?yàn)闊o(wú)論執(zhí)行if里面的語(yǔ)句還是else里面的語(yǔ)句,t都要加1,所以把t移出來(lái).t++;}//2.//把有剩余數(shù)據(jù)的一邊的的數(shù)據(jù)依次全部填充到temp//由上述循環(huán)條件:i<=mid&&j<=right 可知 //此時(shí)要么要么j>right i>mid while(i<=mid) {temp[t]=arr[i];t++;i++;}while(j<=right) {temp[t]=arr[j];t++;j++;}//3.//把temp的數(shù)組轉(zhuǎn)移到arr上int n=0;while(n<arr.length){arr[n]=temp[n];n++;}System.out.println(Arrays.toString(arr));}}

運(yùn)行結(jié)果:

2.分組

寫黑框里面的代碼:

又回到初始,我們?nèi)绾螐陌褦?shù)組分成 黑框這樣子呢?

?運(yùn)用了遞歸的思想進(jìn)行分:

方法:

/*** 分* @param arr 排序的原始數(shù)組* @param left 左邊有序序列的初始索引* @param right 右邊索引* @param temp 做中轉(zhuǎn)的數(shù)組*/public static void mergeSort(int[] arr,int left,int right,int[] temp) {//求中間索引int mid=(left+right)/2;if(left<right) {//左邊遞歸分解mergeSort(arr,left,mid,temp);//右邊遞歸分解mergeSort(arr,mid+1,right,temp);System.out.println(" 最左邊索引:"+left+"\t最右邊邊索引:"+right+"\t"+Arrays.toString(arr));}}

主函數(shù):

public static void main(String[] args) {int arr[]= {8,4,5,7,1,3,6,2};//假設(shè)已經(jīng)到最后一步int arrys[]= {4 ,5 ,7 ,8,1 ,2, 3, 6};int[] add=new int[8];//第一個(gè)參數(shù)表示傳入數(shù)組{4 ,5 ,7 ,8,1 ,2, 3, 6}//第二個(gè)參數(shù)表示這個(gè)數(shù)組的第一個(gè)位置 即是0//第三個(gè)參數(shù)表示這個(gè)數(shù)組的中間位置 (0+7)/2=3//第四個(gè)參數(shù) 存放臨時(shí)數(shù)組的 // merge(arrys,0,3,7,add);mergeSort(arr,0,7,add);}

結(jié)果:

?

或許有一部分同學(xué),看到 結(jié)果會(huì)有疑問(wèn)。那就是 你遞歸基礎(chǔ)比較差,別怕,我給你做詳細(xì)講解。

如果沒(méi)有問(wèn)題的,可以跳過(guò)以下疑問(wèn):

疑問(wèn)1:為啥數(shù)組沒(méi)有變化?

因?yàn)?我們只是分,而沒(méi)有改變數(shù)組的位置

疑問(wèn)2:為啥為輸出7次?

如下圖所示,我們總共分了7次,所以輸出7次

?疑問(wèn)3:最左邊索引 和 最右邊索引 是啥意思?

?這是為了方便大家理解 遞歸的順序 特意加上去的

第一行的? 左:0? 右:1? ? ??表示:? 最左邊索引為:0? 最右邊索引為:1

然后你再看下圖:

故此遞歸的順序:

相信此時(shí),同學(xué)們會(huì)加深對(duì)遞歸的順序的了解

我們來(lái),分析一下,我們完成的部分:

?我們完成了?數(shù)組 的部分,然后→? ?治(組合)? 我們是把 2個(gè)含4個(gè)有序數(shù)字組合成 1個(gè)有序的數(shù)組。

我們可以把先前的? ?治(組合)從原來(lái):把 2個(gè)含4個(gè)有序數(shù)字組合成 1個(gè)有序的數(shù)組。修改成:

把 2個(gè)含n個(gè)有序數(shù)字組合成 1個(gè)有序的數(shù)組

不理解的話,看圖:

?這是我們開頭組合的:

那么以下這2步 和上面那個(gè)圖的區(qū)別在于:

上圖:2個(gè)含有4個(gè)有序數(shù)字 組成一個(gè)有序數(shù)組

下2個(gè)圖:2個(gè)含有2個(gè)有序數(shù)字 組成一個(gè)有序數(shù)組

故此:

?我們把之前只適用一種情況的代碼修改成通用的

之前的:

通用的:

//3.//把temp的數(shù)組轉(zhuǎn)移到arr上int n=0;int tempLeft=left;while(tempLeft<=right){arr[tempLeft]=temp[n];n++;tempLeft++;}

改好后我們?cè)诜值姆椒ㄖ?加入組合:

這樣就能實(shí)現(xiàn) 每分一次 組合一次

完整代碼

import java.util.Arrays; import java.util.Scanner;public class xishuarr {public static void main(String[] args) {int arr[]= {8,4,5,7,1,3,6,2};int[] add=new int[arr.length];System.out.println("排序前:"+Arrays.toString(arr));System.out.println("排序過(guò)程:");mergeSort(arr,0,add.length-1,add);System.out.println("排序后:"+Arrays.toString(arr));}/*** 分* @param arr 排序的原始數(shù)組* @param left 左邊有序序列的初始索引* @param right 右邊索引* @param temp 做中轉(zhuǎn)的數(shù)組*/public static void mergeSort(int[] arr,int left,int right,int[] temp) {//求中間索引int mid=(left+right)/2;if(left<right) {//左邊遞歸分解mergeSort(arr,left,mid,temp);//右邊遞歸分解mergeSort(arr,mid+1,right,temp);merge(arr,left,mid,right,temp);System.out.println(" 最左邊索引:"+left+"\t最右邊邊索引:"+right+"\t"+Arrays.toString(arr));}}/*** * @param arr 排序的原始數(shù)組* @param left 左邊有序序列的初始索引* @param mid 中間索引* @param right 右邊索引* @param temp 做中轉(zhuǎn)的數(shù)組*///4 5 7 8 1 2 3 6public static void merge(int[] arr,int left,int mid,int right,int[] temp) {int i=left; //初始i,左邊有序序列的初始索引int j=mid+1; //初始j,右邊有序序列的初始索引int t=0; //指向temp數(shù)組的當(dāng)前索引//1.//先把左右兩邊(有序)的數(shù)據(jù)按照規(guī)則填充到temp數(shù)組//直到左右兩邊的有序序列,有一邊處理完畢為止while(i<=mid&&j<=right) {if(arr[i]<arr[j]) {temp[t]=arr[i++];/*** 這里我們這里是:temp[t]=arr[i++];* 如果不好理解,你可以寫成這樣:* temp[t]=arr[i];i++;*/}else {temp[t]=arr[j++];}//因?yàn)闊o(wú)論執(zhí)行if里面的語(yǔ)句還是else里面的語(yǔ)句,t都要加1,所以把t移出來(lái).t++;}//2.//把有剩余數(shù)據(jù)的一邊的的數(shù)據(jù)依次全部填充到temp//由上述循環(huán)條件:i<=mid&&j<=right 可知 //此時(shí)要么i>mid 要么j>rightwhile(i<=mid) {temp[t]=arr[i];t++;i++;}while(j<=right) {temp[t]=arr[j];t++;j++;}//3.//把temp的數(shù)組轉(zhuǎn)移到arr上int n=0;int tempLeft=left;while(tempLeft<=right){arr[tempLeft]=temp[n];n++;tempLeft++;}}}

結(jié)果:

歡迎老鐵們點(diǎn)贊收藏

總結(jié)

以上是生活随笔為你收集整理的归并排序java(内附超详解图文讲解)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。