[轉載] 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()中使用的是兩兩比較,不存在跳躍,所以歸并排序是穩定的。?

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

謝謝大家。?

圖侵刪

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/540165.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/540165.shtml
英文地址,請注明出處:http://en.pswp.cn/news/540165.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

centos6設置靜態IP

#編輯配置文件,添加修改以下內容 vim /etc/sysconfig/network-scripts/ifcfg-eth0 BOOTPROTOstatic #啟用靜態IP地址 ONBOOTyes #開啟開機自動啟用網絡連接 IPADDR192.168.21.129 #設置IP地址 NETMASK255.255.255.0 #設置子網掩碼 GATEWAY192.168…

[轉載] 1022 D進制的A+B (20分)【java題解】【80ms】

參考鏈接&#xff1a; Java流Stream 題解 使用 toUnsignedString&#xff08;&#xff09;即可 我有仔細讀過toUnsignedString&#xff08;&#xff09;&#xff0c;有興趣可以看看 第3章 java的基本程序設計結構【補缺學習】【注釋與數據類型】【核心技術卷I】 impor…

mysql 5.6.4以上版本innodb支持全文索引的測試

對于mysql 5.6.4以上版本innodb支持全文索引的測試 在mysql官網&#xff0c;innodb引擎在5.6.4版本提供了對全文索引的支持&#xff0c;筆者對此做了測試&#xff0c;發現對中文全文檢索的支持依然不理想&#xff0c;但卻確實提供了對英文的全文支持。 12.9.5 Full-Text Restri…

[轉載] Java字符串分割方法

參考鏈接&#xff1a; Java中的StringTokenizer方法的示例 2 [sizemedium]1.用split()方法進行分割&#xff0c;分割開的子字符串放入數組&#xff0c;然后進行處理。 示例代碼如下&#xff1a; public class SplitTest { /** * param args * author colin */ …

[轉載] Java StringBuilder StringJoiner

參考鏈接&#xff1a; 何時在StringBuilder上使用StringJoiner 1. StringBuilder Java編譯器對String做了特殊處理&#xff0c;使得我們可以直接用拼接字符串。 雖然可以直接拼接字符串&#xff0c;但是&#xff0c;在循環中&#xff0c;每次循環都會創建新的字符串對象&a…

EMC VMAX的磁盤構成,fast policy(重要)

首先是流程&#xff0c; 不同種類的磁盤&#xff08;sata&#xff0c;fc&#xff0c;flah&#xff09;->disk group->raid->DATA volume->thin pool->TDEV and BCVDEV (lun) 然后細看&#xff1a; 1&#xff09; 不同種類的磁盤叫做disk&#xff0c;這是可見的物…

[轉載] Java反射是什么?看這篇絕對會了!

參考鏈接&#xff1a; Java中的util.Arrays與Reflection.Array的示例 作者&#xff1a;火星十一郎 https://www.cnblogs.com/hxsyl 一.概念 反射就是把Java的各種成分映射成相應的Java類。 Class類的構造方法是private&#xff0c;由JVM創建。 反射是java語言的一個特性…

[精講-3]Offline Domain Join

從windows 2008 ,windows 7開始起就具備脫機加入域的功能,就是它們在未連接DC的情況下,也可以加入域. 假如環境lab.com ,一臺已加入域的PC (WIN7Client) 和即將加入域的PC(win7-2) 在win7client上run下面這個命令 DC已作了一次預先的動作:創建了computer object 在win7-2上,用本…

[轉載] Java——toArray,集合轉換為數組

參考鏈接&#xff1a; 從ArrayList到Java的Array數組轉換&#xff1a;toArray()方法 package day04; import java.util.ArrayList; import java.util.Collection; /** * 集合轉換為數組 * Collection中定義了兩個方法 * Object[] toArray * <T>Y[] toArray(T[] array) …

c#匿名方法

//以下示例和說明都源于《visual c# 2005 技術內幕》 //匿名函數就是沒有名字的函數&#xff0c;是專用于委托的函數。 using System; using System.Collections.Generic; using System.Text; namespace 匿名方法 { public delegate void DelegateClass(); public dele…

[轉載] JAVA8 創建流的5種方式

參考鏈接&#xff1a; 用Java創建流的10種方法 java8中的流式操作是一個很重要的內容 1、通過 stream 方法把 List 或數組轉換為流&#xff0c;如Arr.stream()&#xff1b; //通過stream方法把List或數組轉換為流 Arrays.asList("a1", "a2", "a3&…

用戶反饋:對 Rafy 開發框架的一些個人建議

對Rafy開發框架的一些個人建議 1、潛在使用群體分析 個人認為使用類似Rafy、AgileEAS.NET、PDF.NET及OpenWorks框架的群體主要為以下幾種&#xff1a; 1.1、小微軟件企業 小微軟件企業&#xff0c;這類軟件公司的開發人員一般在10人以下&#xff0c;多以項目實施為主基本談不上…

[轉載] Java8新特新--Stream語法應用在ArrayList的元素移除和排序

參考鏈接&#xff1a; 如何在Java 8中打印Stream的元素 單元測試&#xff1a; Test public void Test02(){ // 源 ArrayList<Integer> IdsSour new ArrayList<>(); IdsSour.add(5); IdsSour.add(1); IdsSour.add(3); IdsSour.add(2); IdsSour.add(6); IdsSour.a…

搭建iscsi存儲系統

搭建iscsi存儲系統 NAS和SAN服務器概述 NAS網絡附屬存儲&#xff1a; NAS&#xff08;Network Attached Storage)&#xff0c;NAS服務器是連接在網絡上&#xff0c;具備資料存儲功能的服務器&#xff0c;一種與用數據存儲服務器。網絡附屬存儲基于標準網絡協議&#xff08;Tcp/…

[轉載] Java8 Stream流遍歷 如何使用索引

參考鏈接&#xff1a; Java 8中迭代帶有索引的流Stream 1. 問題來源 Java8的Stream流為我們的遍歷集合帶來了方便&#xff0c;基本可以取代for循環了。但是有一些情況需要知道當前遍歷的索引&#xff0c;使用for循環當然可以輕易獲得&#xff0c;但使用stream就很難了。 比如…

Jquery簡單的右側浮動菜單

今天有空稍微看了下Jquery動畫函數animate這個方法&#xff0c;發現可以用這個方法來做下簡單的右側浮動菜單 因為經常做淘寶頁面時候會碰到這樣的效果 以前都是用人家的javascript組件代碼 發現老是用人家也不好&#xff0c;所以今天有空用jqeury中的animate這個方法寫了一個簡…

[轉載] Java8-Stream API 詳解

參考鏈接&#xff1a; 如何在Java 8中從Stream獲取ArrayList 摘要 Stream 作為 Java 8 的一大亮點&#xff0c;它與 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念。它也不同于 StAX 對 XML 解析的 Stream&#xff0c;也不是 Amazon Kinesis 對大數據實時處理…

在Microsoft System Center中利用您的現有投資管理VMware--Veeam MP v6.5

在 Microsoft System Center 中利用您的現有投資管理 VMware VeeamManagement Pack (MP) v6.5 適用于物理、虛擬和備份基礎架構的單一的虛擬管理平臺 前段時間介紹了Veeam Management Pack (MP) v6.0產品&#xff0c;昨天發布了新版本VeeamManagement Pack (MP) v6.5&#xff0…

[轉載] Java關鍵字(Java 8版本)

參考鏈接&#xff1a; 所有Java關鍵字列表 定義 被Java語言賦予了特殊含義&#xff0c;用作專門用途的字符串&#xff08;單詞&#xff09;&#xff0c;這些關鍵字不能用于常量、變量、和任何標識符的名稱。 Java關鍵字(Java 8版本) Java關鍵字(Java 8 以后版本) 注意事…

uiw 1.2.17 發布,基于 React 16 的組件庫

發布&#xff0c; 高品質的UI工具包&#xff0c;React 16的組件庫。 文檔網站&#xff1a;uiw-react.github.io開源倉庫&#xff1a;github.com/uiw-react/u… 更新內容&#xff1a; ? 修復沒有代碼檢測文件匹配*.css。 5712887 ? 添加 .editorconfig 文件. d82dabf ? 給測試…