成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

今天說的是必須要熟練掌握的歸并排序

開發(fā) 前端
歸并排序是必須要熟練掌握的排序算法,是面試高頻考點,下面我們就一起來扒一扒歸并排序吧,原理很簡單,大家一下就能搞懂。

 之前給大家介紹了幾個簡單排序,大家只需了解即可,下面介紹的大家就需要熟練掌握了,是面試高頻考點,該文章分別用了遞歸法和迭代法實現(xiàn) 2 路歸并,希望對大家有一丟丟的幫助。

歸并排序 (Merge Sort)

歸并排序是必須要熟練掌握的排序算法,是面試高頻考點,下面我們就一起來扒一扒歸并排序吧,原理很簡單,大家一下就能搞懂。

袁記菜館內(nèi)

第 23 屆食神爭霸賽開賽啦!

袁廚想在自己排名前4的分店中,挑選一個最優(yōu)秀的廚師來參加食神爭霸賽,選拔規(guī)則如下。

第一場 PK:每個分店選出兩名廚師,首先進行店內(nèi) PK,選出店內(nèi)里的勝者

第二場 PK: 然后店內(nèi)的優(yōu)勝者代表分店挑戰(zhàn)其他某一分店的勝者(半決賽)

第三場 PK:最后剩下的兩名勝者進行PK,選出最后的勝者。

示意圖如下

廚神爭霸賽

上面的例子大家應該不會陌生吧,其實我們歸并排序和食神選拔賽的流程是有些相似的,下面我們一起來看一下歸并排序吧。

歸并這個詞語的含義就是合并,并入的意思,而在我們的數(shù)據(jù)結(jié)構(gòu)中的定義是將兩個或兩個以上的有序表合成一個新的有序表。而我們這里說的歸并排序就是使用歸并的思想實現(xiàn)的排序方法。

歸并排序使用的就是分治思想。顧名思義就是分而治之,將一個大問題分解成若干個小的子問題來解決。小的子問題解決了,大問題也就解決了。分治后面會專門寫一篇文章進行描述,這里先簡單提一下。

下面我們通過一個圖片來描述一下歸并排序的數(shù)據(jù)變換情況,見下圖。

歸并排序

我們簡單了解了歸并排序的思想,從上面的描述中,我們可以知道算法的歸并過程是比較難實現(xiàn)的,這也是這個算法的重點,我們先通過一個視頻來看一下歸并函數(shù)的具體步驟,看完我們這個視頻就能懂個大概啦。

視頻號

視頻中歸并步驟大家有沒有看懂呀,沒看懂也不用著急,下面我們一起來拆解一下,歸并過程共分三步走。

第一步:創(chuàng)建一個額外大集合用于存儲歸并結(jié)果,長度則為那兩個小集合的和,從視頻中也可以看出

第二步:我們從左自右比較兩個指針指向的值,將較小的那個存入大集合中,存入之后指針移動,并繼續(xù)比較,直到某一小集合的元素全部都存到大集合中。見下圖

合并

第三步:當某一小集合元素全部放入大集合中,則需將另一小集合中剩余的所有元素存到大集合中,見下圖

好啦,看完視頻和圖解是不是能夠?qū)懗鰝€大概啦,了解了算法原理之后代碼寫起來就很簡單啦,

下面我們看代碼吧。

注:這里用了System.arraycopy(),大家也可以使用其他方法,其中的五個參數(shù)分別是,源數(shù)組,目的數(shù)組,源數(shù)組起始索引,目的數(shù)組放置的起始索引,復制的長度

  1. class Solution { 
  2.     public int[] sortArray(int[] nums) { 
  3.         mergeSort(nums,0,nums.length-1); 
  4.         return nums; 
  5.     } 
  6.     public void mergeSort(int[] arr, int leftint right) { 
  7.         if (left < right) { 
  8.             int mid = left + ((right - left) >> 1); 
  9.             mergeSort(arr,left,mid); 
  10.             mergeSort(arr,mid+1,right); 
  11.             merge(arr,left,mid,right); 
  12.         } 
  13.     }  
  14.     //歸并 
  15.     public void merge(int[] arr,int leftint mid, int right) { 
  16.         //第一步,定義一個新的臨時數(shù)組 
  17.         int[] temparr = new int[right -left + 1]; 
  18.         int temp1 = left, temp2 = mid + 1; 
  19.         int index = 0; 
  20.         //對應第二步,比較每個指針指向的值,小的存入大集合 
  21.         while (temp1 <= mid && temp2 <= right) { 
  22.             if (arr[temp1] <= arr[temp2]) { 
  23.                 temparr[index++] = arr[temp1++]; 
  24.             } else { 
  25.                 temparr[index++] = arr[temp2++]; 
  26.             } 
  27.         } 
  28.         //對應第三步,將某一小集合的剩余元素存到大集合中 
  29.         if (temp1 <= mid) System.arraycopy(arr, temp1, temparr, index, mid - temp1 + 1); 
  30.         if (temp2 <= right) System.arraycopy(arr, temp2, temparr, indexright -temp2 + 1);     
  31.         System.arraycopy(temparr,0,arr,0+left,right-left+1);  
  32.     } 

歸并排序時間復雜度分析

我們一趟歸并,需要將兩個小集合的長度放到大集合中,則需要將待排序序列中的所有記錄掃描一遍所以時間復雜度為O(n)。

歸并排序把集合一層一層的折半分組,則由完全二叉樹的深度可知,整個排序過程需要進行 logn(向上取整)次,則總的時間復雜度為 O(nlogn)。

另外歸并排序的執(zhí)行效率與要排序的原始數(shù)組的有序程度無關(guān),所以在最好,最壞,平均情況下時間復雜度均為 O(nlogn) 。

雖然歸并排序時間復雜度很穩(wěn)定,但是他的應用范圍卻不如快速排序廣泛,這是因為歸并排序不是原地排序算法,空間復雜度不為 O(1),那么他的空間復雜度為多少呢?

歸并排序的空間復雜度分析

歸并排序所創(chuàng)建的臨時結(jié)合都會在方法結(jié)束時釋放,單次歸并排序的最大空間是 n ,所以歸并排序的空間復雜度為 O(n).

歸并排序的穩(wěn)定性分析

歸并排序的穩(wěn)定性,要看我們的 merge 函數(shù),我們代碼中設置了 arr[temp1] <= arr[temp2] ,當兩個元素相同時,先放入arr[temp1] 的值到大集合中,所以兩個相同元素的相對位置沒有發(fā)生改變,所以歸并排序是穩(wěn)定的排序算法。

等等還沒完嘞,不要走呀。

歸并排序的遞歸實現(xiàn)是比較常見的,也是比較容易理解的,下面我們一起來扒一下歸并排序的迭代寫法。看看他是怎么實現(xiàn)的。

我們通過一個視頻來了解下迭代方法的思想

視頻號

是不是通過視頻了解個大概啦,下面我們來對視頻進行解析。

迭代實現(xiàn)的歸并排序是將小集合合成大集合,小集合大小為 1,2,4,8,…..。依次迭代,見下圖

比如此時小集合大小為 1 。兩個小集合分別為 [3],[1]。

然后我們根據(jù)合并規(guī)則,見第一個視頻,將[3],[1]合并到臨時數(shù)組中,則小的先進,進而實現(xiàn)了排序,然后再將臨時數(shù)組的元素復制到原來數(shù)組中。則實現(xiàn)了一次合并。

下面則繼續(xù)合并[4],[6]。具體步驟一致。所有的小集合合并完成后,則小集合的大小變?yōu)?2,繼續(xù)執(zhí)行剛才步驟,見下圖。

此時子集合的大小為 2 ,則為 [2,5],[1,3] 繼續(xù)按照上面的規(guī)則合并到臨時數(shù)組中完成排序。這就是迭代法的具體執(zhí)行過程,

下面我們直接看代碼吧。

注:遞歸法和迭代法的 merge 函數(shù)代碼一樣。

  1. class Solution { 
  2.     public int[] sortArray (int[] nums) { 
  3.         //代表子集合大小,1,2,4,8,16..... 
  4.         int k = 1; 
  5.         int len = nums.length; 
  6.         while (k < len) { 
  7.             mergePass(nums,k,len); 
  8.             k *= 2; 
  9.         } 
  10.         return nums; 
  11.  
  12.     } 
  13.     public void mergePass (int[] array, int k, int len) { 
  14.  
  15.          int i; 
  16.          for (i = 0; i < len-2*k; i += 2*k) { 
  17.              //歸并 
  18.              merge(array,i,i+k-1,i+2*k-1); 
  19.          } 
  20.          //歸并最后兩個序列 
  21.          if (i + k < len) { 
  22.              merge(array,i,i+k-1,len-1); 
  23.          } 
  24.  
  25.     } 
  26.      public void merge (int[] arr,int leftint mid, int right) { 
  27.         //第一步,定義一個新的臨時數(shù)組 
  28.         int[] temparr = new int[right -left + 1]; 
  29.         int temp1 = left, temp2 = mid + 1; 
  30.         int index = 0; 
  31.         //對應第二步,比較每個指針指向的值,小的存入大集合 
  32.         while (temp1 <= mid && temp2 <= right) { 
  33.             if (arr[temp1] <= arr[temp2]) { 
  34.                 temparr[index++] = arr[temp1++]; 
  35.             } else { 
  36.                 temparr[index++] = arr[temp2++]; 
  37.             } 
  38.         } 
  39.         //對應第三步,將某一小集合的剩余元素存到大集合中 
  40.         if (temp1 <= mid) System.arraycopy(arr, temp1, temparr, index, mid - temp1 + 1); 
  41.         if (temp2 <= right) System.arraycopy(arr, temp2, temparr, indexright -temp2 + 1);    
  42.         //將大集合的元素復制回原數(shù)組 
  43.         System.arraycopy(temparr,0,arr,0+left,right-left+1);  
  44.     } 

通過上面的視頻解析和代碼,希望大家能夠?qū)w并排序給拿下,下面會給大家寫一下,歸并排序在實際刷題時的應用,感謝閱讀。

本文轉(zhuǎn)載自微信公眾號「袁廚的算法小屋」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系袁廚的算法小屋 公眾號。

 

責任編輯:武曉燕 來源: 袁廚的算法小屋
相關(guān)推薦

2021-01-16 11:44:46

編程語言開發(fā)

2009-12-04 08:53:49

TechNet雜志

2020-01-09 08:26:16

代碼JS開發(fā)

2009-12-16 17:31:30

Ruby on Rai

2021-12-03 18:04:06

命令 RabbitMQ Web

2019-07-11 10:45:34

MQ中間件 API

2018-06-12 15:55:07

編程語言Java加密方式

2019-08-07 15:20:08

Git開源命令

2009-07-15 09:09:45

Vim編輯器使用Vim備份

2021-03-01 08:02:55

算法排序操作

2009-10-29 15:50:49

VB.NET Exce

2011-04-20 14:29:07

歸并排序

2019-06-20 17:39:12

Android啟動優(yōu)化

2023-10-09 07:11:03

排序算法序列

2021-10-21 08:13:11

Springboot

2015-05-07 15:13:22

JS實現(xiàn)JQueryJQuery

2019-12-27 15:05:11

LinuxWindowsDNS

2022-04-06 08:58:39

歸并排序Go算法

2020-04-08 17:10:03

GitHub代碼開源

2019-05-27 10:20:45

點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 在线免费观看成人 | 国产精品99 | 欧美午夜精品 | 国产午夜精品久久久 | 欧美成人一区二免费视频软件 | 亚洲毛片 | 日韩免费视频一区二区 | 国产日韩精品视频 | 精品一区国产 | 欧美三级视频在线观看 | 欧美日韩精品一区 | 欧美一区二区三区 | 欧美一级片黄色 | 日韩一区在线播放 | 日韩在线综合网 | 日本不卡免费新一二三区 | 欧美精品电影一区 | 欧美三区 | 午夜羞羞 | 成人激情视频在线播放 | 97偷拍视频 | 成年人免费网站 | 成人国产免费视频 | 久久久久久久久99 | 一区二区三区视频 | 日韩欧美亚洲 | 午夜天堂精品久久久久 | 久久久资源 | 亚洲欧美精品国产一级在线 | 观看毛片 | 欧美精品日韩 | 日韩精品一区在线观看 | 中文在线一区二区 | 精品1区 | 91av久久久| 亚洲精品一区二区三区蜜桃久 | 亚洲美女网站 | 国产电影一区二区三区爱妃记 | 国产视频在线观看一区二区三区 | 玖玖视频免费 | 午夜精品久久久久99蜜 |