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

歡迎訪問 生活随笔!

生活随笔

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

java

[转载] Java实现归并排序(超详细,新手请进)

發布時間:2025/3/11 java 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [转载] Java实现归并排序(超详细,新手请进) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

參考鏈接: Java中將數組合并為的新數組

歸并排序?

大家好,這是我第一次在CSDN上寫東西,因為我一直覺得有需要就去找別人的blog看看就好,但我發現自己寫出來的東西確實能加深記憶。我半路出家,屬實是個菜鳥,文章也許寫的會有很多問題,還望大家多多包涵,歡迎指正。 最近在學數據結構,數據結構作為程序員該有的基本內功,無疑是我們要多加練習的。然而最為菜鳥的我,在學習的過程中也發現很多坑在大佬眼里不就是一句話的事 ,我寫的這些既是為了幫助有需要的人,也是對自己的鍛煉以及記錄。廢話到此結束,再多說要被錘了。?

代碼打頭?

~~廢話不多說先上代碼,如果代碼都跑不出,大家就可以散了。~~?

?

?

import java.util.Arrays;

?

public class mergeSortDemo {

? ? public static void main(String[] args) {

? ? ? ? int arr[] = new int[10];

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

? ? ? ? ? ? arr[i] = (int) (Math.random()*100);

? ? ? ? }

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

? ? ? ? ? ? System.out.print(arr[i]+" ");

? ? ? ? }

? ? ? ? System.out.println("~~~~~~~~~~");

? ? ? ? mergeSort(arr,0,9);

? ? }

?

? ? public static void merge(int arr[],int low,int mid,int high){

? ? ? ? int i = low;

? ? ? ? int j = mid+1;

? ? ? ? int t = 0;

? ? ? ? int temp[] = new int[high-low+1];

? ? ? ? while (i<=mid && j<=high){

? ? ? ? ? ? if (arr[i]<arr[j]){

? ? ? ? ? ? ? ? temp[t++] = arr[i++];

? ? ? ? ? ? }

? ? ? ? ? ? else {

? ? ? ? ? ? ? ? temp[t++] = arr[j++];

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? //

? ? ? ? while (i<=mid){

? ? ? ? ? ? temp[t++] = arr[i++];

? ? ? ? }

? ? ? ? while (j<=high){

? ? ? ? ? ? temp[t++] = arr[j++];

? ? ? ? }

? ? ? ? //

? ? ? ? for (int tempLeft=0;tempLeft<temp.length;tempLeft++){

? ? ? ? ? ? arr[low+tempLeft] = temp[tempLeft];

? ? ? ? }

? ? }

? ? public static void mergeSort(int arr[],int low,int high){

? ? ? ? int mid = (low+high)/2;

? ? ? ? if (low<high) {

? ? ? ? ? ? mergeSort(arr, low, mid);

? ? ? ? ? ? mergeSort(arr, mid+1, high);

? ? ? ? ? ? //

? ? ? ? ? ? merge(arr,low,mid,high);

? ? ? ? ? ? System.out.println( Arrays.toString(arr));

? ? ? ? }

? ? }

}

?

?

?

是不是被這精妙的邏輯給迷住了。 何謂歸并排序,歸并排序就是divide-and-merge。?

如圖,算法的基本做法是:先分割數字,再按照每組的的大小排序,兩個小組變為中組,兩個中組合為大組。??

整體思路?

歸并排序首先需要將數組拆分,然后治之。具體為,將一串數組分為兩半,再各自對兩半繼續拆分,直至每組的的元素個數為一。此時開始治:如圖中將數據分到最后一步,則上層長度為2,用當前的兩個數組,按照算法來排序整合merge(){① 比較兩個數組中的每一個數,將當前索引指向的較小的數裝入臨時數組temp中;② 當一組數據全部裝入temp中時,一定會出現一種情況,另一組一定還有數據沒存進去,所以將剩下的數存入temp;③ 這是比較難想到的一點:存入temp后,還需要返回到原先數組arr【】中去。但注意,雖然每次都是返回去的下標都是從0—>length-1,但不是一次性的。因為整個排序不是一次排好,每次小組內排完就需要存回arr,由此可知,不可能只用回傳一次,但每次當然要把所有數據都穿回去,但是是分批進行,這也是這個算法的難點與精髓所在。為了方便理解,我用迭代的方式向大家展示:最后一次(也是最接近排序完成的一次)是兩個數組合并為一個,這一個temp傳回給arr【】,是從temp【0】->temp【length-1】。倒數第二次:temp【0】->temp【mid】,temp【mid+1】->temp【length-1】…第一次:兩兩回傳,(可能是)temp【0】->temp【1】,temp2->temp3依次類推。這就肯定需要循環來定位索引。?

到此可以將上述方法抽象為 mergeSort()和merge()。mergeSort()多次遞歸調用自己而每次調用意味著分,分則要治,治則是在調用后用merge()。?

從圖上可以清晰的看出,整個操作是棧式操作,先分的最后再合,當然遞歸本身就是棧式操作,我之所以這樣說是為了讓大家再順著思路分析下來能知道如何去編寫這樣的程序。有了這些,我們開始逐句翻譯就好了。 我們知道需要一個分的總函數以及每次幫忙合的子函數,總函數遞歸調用自己和子函數就完成了。故此,我們開始子函數的編寫,也是按照之前的思路。?

實現?

merge(){①比較兩個數組中的每一個數,將當前索引指向的較小的數裝入臨時數組temp中;?

merge(int arr[],int low,int mid,int high){

? ? ? ? ? ? int i = low;

? ? ? ? ? ? int j = mid+1;

? ? ? ? ? ? int t = 0;

? ? ? ? ? ? int temp[] = new int[high-low+1];

? ? ? ? while (i<=mid && j<=high){

? ? ? ? ? ? if (arr[i]<arr[j]){

? ? ? ? ? ? ? ? temp[t++] = arr[i++];

? ? ? ? ? ? }

? ? ? ? ? ? else {

? ? ? ? ? ? ? ? temp[t++] = arr[j++];

? ? ? ? ? ? }

?

?

②當一組數據全部裝入temp中時,一定會出現一種情況,另一組一定還有數據沒存進去,所以將剩下的數存入temp;?

?while (i<=mid){

? ? ? ? ? ? temp[t++] = arr[i++];

? ? ? ? }

? ? ? ? while (j<=high){

? ? ? ? ? ? temp[t++] = arr[j++];

? ? ? ? }

?

?

③ 這是比較難想到的一點:存入temp后,還需要返回到原先數組arr【】中去。但注意,雖然每次都是返回去的下標都是從0—>length-1,但不是一次性的。因為整個排序不是一次排好,每次小組內排完就需要存回arr,由此可知,不可能只用回傳一次,但每次當然要把所有數據都穿回去,但是是分批進行,這也是這個算法的難點與精髓所在。為了方便理解,我用迭代的方式向大家展示:最后一次(也是最接近排序完成的一次)是兩個數組合并為一個,這一個temp傳回給arr【】,是從temp【0】->temp【length-1】。倒數第二次:temp【0】->temp【mid】,temp【mid+1】->temp【length-1】…第一次:兩兩回傳,(可能是)temp【0】->temp【1】,temp2->temp3依次類推。這就肯定需要循環來定位索引。?

for (int tempLeft=0;tempLeft<temp.length;tempLeft++){

? ? ? ? ? ? arr[low+tempLeft] = temp[tempLeft];

? ? ? ? }

?

?

mergeSort()多次遞歸調用自己而每次調用意味著分,分則要治,治則是在調用后用merge()。 我們都知道要一分為二二分為四,到元素為一時結束,反過來怎么寫循環呢。當length=1 則(0+1)/2=0 此時low=high 反過來 low<high則可以不停分解?

mergeSort(int arr[],int low,int high){

? ? ? ? int mid = (low+high)/2;

? ? ? ? if (low<high) {

? ? ? ? ? ? mergeSort(arr, low, mid);

? ? ? ? ? ? mergeSort(arr, mid+1, high);

? ? ? ? ? ? //

? ? ? ? ? ? merge(arr,low,mid,high);

? ? ? ? ? ? System.out.println( Arrays.toString(arr));

? ? ? ? }

? ? }

?

?

分析?

首先要將整個數組遍歷一遍,歸并排序要進行log2n次,總共的時間復雜度為O(nlog2n)?

遞歸深度為log2n 額外的數組空間 n 總的空間復雜度為O(n+log2n)?

再merge()中使用的是兩兩比較,不存在跳躍,所以歸并排序是穩定的。?

換而言之,歸并排序是一種空間換時間的算法。?

謝謝大家。?

圖侵刪

總結

以上是生活随笔為你收集整理的[转载] Java实现归并排序(超详细,新手请进)的全部內容,希望文章能夠幫你解決所遇到的問題。

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