頑固なマージソートアルゴリズム

頑固なマージソートアルゴリズム

この記事はWeChatの公開アカウント「Beta Learns JAVA」から転載したもので、著者はSilently9527です。この記事を転載する場合は、Beta Learning JAVA パブリック アカウントにお問い合わせください。

序文

この記事では、マージ操作に基づいてソートを完了するアルゴリズムについて説明します。

マージソートアルゴリズムのアイデア

配列をソートするには、まず配列を 2 つの配列に分割して別々にソートし、次に結果をマージして、配列全体がソートされるまでこのプロセスを再帰的に繰り返します。これがマージ ソートのアルゴリズムの考え方です。

マージソートの利点は、任意の長さ N の配列をソートするのに必要な時間が NlogN に比例することを保証できることです。これはプライマリソートでは実現できない利点です。

欠点は、マージ操作では追加の配列の導入が必要となり、追加のスペースが N に比例することです。

インプレースマージの実装

マージソートを実装する前に、2 つの順序付き配列のマージ操作を完了する必要があります。つまり、2 つの順序付き配列を 1 つの順序付き配列にマージする必要があります。

  • このプロセスでは、補助配列を導入する必要があります。
  • 定義されているメソッド シグネチャは merge(a, lo, mid, hi) です。このメソッドは、配列 a[lo..mid] と a[mid..hi] を順序付けられた配列にマージし、その結果を a[lo..mid] に格納します。
  • このメソッドでは、前回の記事で説明したパブリック関数をあまり使用する必要はありません。前回の記事「一般的なプライマリソートアルゴリズム、今回はすべて理解する」を参照してください。
  1. パブリッククラス MergeSort は SortTemplate を実装します {
  2. プライベートComparable[] aux;
  3.  
  4. @オーバーライド
  5. パブリックvoid ソート(比較可能な[] 配列) {
  6. //実装予定
  7. }
  8.  
  9. プライベートvoidマージ(比較可能[] a、 int lo、 int mid、 int hi) {
  10. ( int i = lo; i <= hi; i++) {
  11. 補助[i] = a[i];
  12. }
  13. int i = lo、j = mid + 1;
  14. ( int k = lo; k <= hi; k++) {
  15. もし(i>中間){
  16. a[k] = aux[j++];
  17. }そうでなければ (j > hi) {
  18. a[k] = aux[i++];
  19. } そうない場合 (aux[i], aux[j]) {
  20. a[k] = aux[i++];
  21. }それ以外{
  22. a[k] = aux[j++];
  23. }
  24. }
  25. }
  26.  
  27. }

トップダウンマージソート

分割統治の考え方に基づいて、大きな配列は、最初に小さな配列に再帰的に分割し、小さな配列が整然と並んでいることを確認してから、配列全体が整然と並ぶまでそれらをマージすることによってソートされます。この操作は、トップダウンマージソートと呼ばれます。

  1. パブリッククラス MergeSort は SortTemplate を実装します {
  2. プライベートComparable[] aux;
  3.  
  4. @オーバーライド
  5. パブリックvoid ソート(比較可能な[] 配列) {
  6. aux = 新しいComparable[配列.長さ];
  7. doSort(配列、0、配列の長さ - 1);
  8. }
  9.  
  10. プライベートvoid doSort(Comparable[]配列、 int lo、 int hi) {
  11. (最低 >= 最高)の場合{
  12. 戻る;
  13. }
  14. int mid = (hi - lo) / 2 + lo;
  15. doSort(配列、lo、mid);
  16. doSort(配列、mid + 1、hi);
  17. マージ(配列、lo、mid、hi);
  18. }
  19.  
  20. プライベートvoidマージ(比較可能[] a、 int lo、 int mid、 int hi) {
  21. //省略
  22. }
  23.  
  24. }

上記のコードは標準的な再帰マージソート操作ですが、慎重に検討すればアルゴリズムを最適化できます。

「配列がすでに順序付けられているかどうかをテストする」; a[mid]<=a[mid+1]の場合、マージメソッドをスキップしてマージ操作を減らすことができます。修復後のdoSortメソッド

  1. プライベートvoid doSort(Comparable[]配列、 int lo、 int hi) {
  2. (最低 >= 最高)の場合{
  3. 戻る;
  4. }
  5. int mid = (hi - lo) / 2 + lo;
  6. doSort(配列、lo、mid);
  7. doSort(配列、mid + 1、hi);
  8. 配列[mid].compareTo(配列[mid + 1]) >= 0の場合{
  9. マージ(配列、lo、mid、hi);
  10. }
  11. }

「小さな配列の場合は、挿入ソートを使用できます」。小さな配列にマージソートを使用すると再帰呼び出しスタックが増加するため、サブ配列のソートを処理するために挿入ソートを使用することを検討できます。

  1. プライベートvoid doSort(Comparable[]配列、 int lo、 int hi) {
  2. (最低 >= 最高)の場合{
  3. 戻る;
  4. }
  5.  
  6. if (hi - lo < 5) { //テスト、5未満の場合、挿入ソートを使用する
  7. 挿入ソート(配列、lo、hi);
  8. 戻る;
  9. }
  10.  
  11. int mid = (hi - lo) / 2 + lo;
  12. doSort(配列、lo、mid);
  13. doSort(配列、mid + 1、hi);
  14. if (less(配列[mid + 1], 配列[mid])) {
  15. マージ(配列、lo、mid、hi);
  16. }
  17. }
  18.  
  19. // ソートを挿入
  20. プライベートvoid挿入ソート(比較可能な配列[]、 int lo、 int hi) {
  21. ( int i = lo; i <= hi; i++) {
  22. for ( int j = i; j > lo && less(array[j], array[j - 1]); j --) {  
  23. exch(配列、j、j - 1);
  24. }
  25. }
  26. }

「補助配列に要素をコピーする時間を節約する」; この操作を実装するのはより面倒であり、再帰の各レベルで入力データと出力配列の役割を交換する必要があります。変更後の完全なコードは次のとおりです。

  1. パブリッククラス MergeSort は SortTemplate を実装します {
  2. プライベートComparable[] aux;
  3.  
  4. @オーバーライド
  5. パブリックvoid ソート(比較可能な[] 配列) {
  6. aux = 配列.clone();
  7. doSort(aux, 配列, 0, 配列の長さ - 1);
  8. }
  9.  
  10. プライベートvoid doSort(Comparable[] src、Comparable[] dest、 int lo、 int hi) {
  11. (最低 >= 最高)の場合{
  12. 戻る;
  13. }
  14.  
  15. if (hi - lo < 5) { //テスト、5未満の場合、挿入ソートを使用する
  16. 挿入ソート(dest, lo, hi);
  17. 戻る;
  18. }
  19.  
  20. int mid = (hi - lo) / 2 + lo;
  21. doSort(dest, src, lo, mid);
  22. doSort(dest, src, mid + 1, hi);
  23. if (less(src[mid + 1], src[mid])) {
  24. マージ(src、dest、lo、mid、hi);
  25. }
  26. }
  27.  
  28. // ソートを挿入
  29. プライベートvoid挿入ソート(比較可能な配列[]、 int lo、 int hi) {
  30. ( int i = lo; i <= hi; i++) {
  31. for ( int j = i; j > lo && less(array[j], array[j - 1]); j --) {  
  32. exch(配列、j、j - 1);
  33. }
  34. }
  35. }
  36.  
  37. プライベートvoidマージ(Comparable[] src、Comparable[] dest、 int lo、 int mid、 int hi) {
  38. int i = lo、j = mid + 1;
  39. ( int k = lo; k <= hi; k++) {
  40. もし(i>中間){
  41. dest[k] = src[j++];
  42. }そうでなければ (j > hi) {
  43. dest[k] = src[i++];
  44. }そうでない場合 (less(src[i], src[j])) {
  45. dest[k] = src[i++];
  46. }それ以外{
  47. dest[k] = src[j++];
  48. }
  49. }
  50. }
  51.  
  52. }

再帰操作の各層はサブ配列をソートしますが、サブ配列はaux[lo..hi]またはa[lo..hi]である可能性があります。doSortの最初の呼び出しではsrc = auxとdest = arrayが渡されるため、再帰の最終結果は配列に入力され、配列全体のソートが完了していることを確認する必要があります。

ボトムアップマージソート

マージ アルゴリズムを実装する別の方法は、最初に小さな配列をマージし、次に配列全体が順序付けられるまでサブ配列をペアでマージすることです。

  1. パブリッククラス MergeSort は SortTemplate を実装します {
  2. プライベートComparable[] aux;
  3.  
  4. @オーバーライド
  5. パブリックvoid ソート(比較可能な[] 配列) {
  6. int長さ = 配列.長さ;
  7. aux = 新しいComparable[長さ];
  8. ( int sz = 1 ; sz < 長さ; sz += sz) {
  9. ( int i = 0; i < 長さ - sz; i += 2 * sz) {
  10. merge(配列、i、i + sz - 1、 Math.min (i + 2 * sz - 1、長さ - 1));
  11. }
  12. }
  13. }
  14.  
  15. プライベートvoidマージ(比較可能[] a、 int lo、 int mid、 int hi) {
  16. ( int i = lo; i <= hi; i++) {
  17. 補助[i] = a[i];
  18. }
  19. int i = lo、j = mid + 1;
  20. ( int k = lo; k <= hi; k++) {
  21. もし(i>中間){
  22. a[k] = aux[j++];
  23. }そうでなければ (j > hi) {
  24. a[k] = aux[i++];
  25. } そうない場合 (aux[i], aux[j]) {
  26. a[k] = aux[i++];
  27. }それ以外{
  28. a[k] = aux[j++];
  29. }
  30. }
  31. }
  32.  
  33. }

<<:  ヒントンは独自に44ページの論文を発表した。「アイデアを出して、自分で試してみて」

>>:  ビッグデータと人工知能 - 機械的思考から統計的思考へ

ブログ    
ブログ    
ブログ    

推薦する

人工知能は諸刃の剣です。EUは利益を促進し、害を避けるための規制を導入しました。

近年、交通と環境に対する要求が継続的に高まっており、わが国の新エネルギー自動車は急速な発展を遂げてい...

世界的なIT大手はAIを活用してデータセンターのエネルギー節約と排出量削減に取り組んでいる

データ センターは、世界中の何十億もの人々が毎日使用するアプリケーション、Web サイト、サービスに...

定量評価、アルゴリズム拡張:強化学習研究の10原則

[[252430]]ビッグデータダイジェスト制作編纂者:江宝尚今年 9 月に開催された Deep L...

...

顔認識防止技術でプライバシー漏洩を防ぐ方法

人工知能監視システムに対する懸念から、研究者たちはそれを標的とするツールの開発に取り組んでいる。最近...

...

2021 年のテクノロジートレンドはどこに向かうのでしょうか? IEEEが答えを教えます

[[357414]]この記事はLeiphone.comから転載したものです。転載する場合は、Leip...

AIが不動産業界をどう変えるのか

デジタル化が進むにつれ、人工知能は不動産経済の成長を促進する上で重要な役割を果たします。有名なソフト...

フォーブス誌の2020年のAIに関するトップ10予測: 人工知能はますます「疎外」されつつある!

人工知能 (AI) は間違いなく 2010 年代のテクノロジーのテーマであり、新しい 10 年が始ま...

顔を自由に編集! Adobe が新世代の GAN アーティファクトを発表: 最大 35 の顔属性の変更をサポート

画像合成における重要な問題は、画像内のエンタングルメント問題です。たとえば、人物の顔にあるすべてのひ...

人工知能が私たちの日常生活を変える5つの方法

人工知能はもはや未来的な概念ではなく、私たちの日常生活に欠かせないものとなっています。私たちが目覚め...

...

AIがコロナホールを発見し宇宙天気予報を自動化

オーストリアのグラーツ大学、スコルテック社、そして米国とドイツの科学者らは、宇宙からの観測からコロナ...

このアリは写真を撮ることができます!プリンストン大学は、50万分の1の大きさに縮小されたミクロンレベルのカメラを開発した。

最近、プリンストン大学の研究者らは、世界初の高品質ミクロンスケール光学イメージングデバイス「ニューラ...