Java ソートアルゴリズムの概要 (VII): クイックソート

Java ソートアルゴリズムの概要 (VII): クイックソート

クイックソートはバブルソートの改良版です。その基本的な考え方は、ソート パスを通じて、ソートするデータが 2 つの独立した部分に分割され、一方の部分のすべてのデータがもう一方の部分のすべてのデータよりも小さくなり、その後、この方法に従って 2 つの部分のデータが別々にすばやくソートされるというものです。ソート プロセス全体を再帰的に実行して、データ全体を順序付けられたシーケンスに変換できます。クイックソートは不安定で、O(log(n)) の追加スペースを必要とし、時間計算量は O(nlog(n)) であり、適応性がありません。

クイックソートには、言及する価値のあるバリエーションがいくつかあります。以下に簡単に紹介します。

ランダム化されたクイックソート:クイックソートの最悪のケースは、各パーティションのピボットの選択に基づきます。基本的なクイックソートでは、最初の要素がピボットとして選択されます。このように、配列がすでに順序付けられている場合、各分割は最悪の結果になります。一般的な最適化方法は、要素をメイン要素としてランダムに選択するランダム化アルゴリズムです。この場合、最悪のケースは依然として O(n^2) ですが、最悪のケースはもはや入力データに依存せず、ランダム関数の評価が不十分なために発生します。実際、クイックソートをランダム化して理論上の最悪のケースを得る確率は 1/(2^n) だけです。したがって、ランダム化クイックソートは、ほとんどの入力データに対して予想される時間計算量 O(nlogn) を達成できます。ある先輩が素晴らしい要約をしてくれました。「ランダムクイックソートは、人の性格のニーズを一生涯満たすことができます。」

ランダム化クイックソートの唯一の欠点は、入力データに同一データが大量に存在すると、ランダム化の効果が直接的に弱まってしまうことです。極端なケース、つまり n 個の同一の数字をソートする場合、ランダムクイックソートの時間計算量は間違いなく O(n^2) に削減されます。解決策は、ピボットを交換せずにそのままの状態でスキャンすることです。

バランス クイックソート: 毎回、中央値をキー データとして表すことができる要素を選択し、通常のクイックソートの原則に従って比較、置換、再帰を実行します。一般的に、このデータを選択する方法は、開始データ、終了データ、中間データを取得し、比較して中央値を選択することです。この3つの値を取る利点は、実際の問題(情報科学のコンテストなど)では、近似連続データや反転データが出現する可能性が高いことです。この場合、真ん中のデータが必然的に中央値になり、実は近似中央値でもあります。中央が大きく両側が小さい(またはその逆)データに遭遇し、取得した値が最大値に近い場合、少なくとも2つの部分を分離できるため、実際の効率は約2倍になり、データを少し乱して縮退構造を破壊することが有益です。

外部クイックソート: 通常のクイックソートとは異なり、キーデータはバッファです。まず、前と次の M/2 要素がバッファに読み込まれ、バッファ内のこれらの要素がソートされます。次に、ソートされた配列の先頭 (または末尾) から次の要素が読み込まれます。この要素がバッファ内の最小の要素よりも小さい場合は、最初の空きスペースに書き込まれます。この要素がバッファ内の最大の要素よりも大きい場合は、最後の空きスペースに書き込まれます。それ以外の場合は、バッファ内の最大または最小の要素が配列に書き込まれ、バッファに配置されます。すでに順序付けされた中間データの再配置を避けるため、最大値はこれらのキー データより低く、最小値はこれらのキー データより高く設定してください。完了後、配列の中央のスペースを空ける必要があり、バッファは配列の中央のスペースに書き込まれます。次に、小さい外側の部分を再帰的にソートし、他の部分を循環的にソートします。

3 方向基数クイックソート (マルチキー クイックソート、マルチキー クイックソートとも呼ばれます) : 基数ソート (一般的な文字列比較ソートは基数ソートであるなど) とクイックソートの特性を組み合わせたもので、文字列ソートに比較的効率的なアルゴリズムです。このアルゴリズムによってソートされる配列の要素には、文字列などのマルチキーという特性があり、各文字はキーとみなすことができます。アルゴリズムは、ソートされた配列内の要素をキー データとしてランダムに選択するたびに、まずこの要素の最初のキー (文字) のみを考慮し、次にキーを比較して、他の要素をキー データより小さい、等しい、大きい 3 つの部分に分割します。次に、このキーの位置に基づいて「より小さい」部分と「より大きい」部分を再帰的にソートし、次のキーに基づいて「等しい」部分をソートします。

コード実装:

  1. 公共 クラスクイックソート{
  2. 公共 静的  void sort(比較可能なデータ[]、 int low、 int high) {
  3. // ピボット要素。通常は最初の要素に基づいて分割されます 
  4. int i = 低い;
  5. 整数j = 高い;
  6. (低<高)の場合{
  7. // 配列の両端から中央まで交互にスキャンします 
  8. 比較可能な pivotKey = data[low];
  9. // ポインタ i、j をスキャンします。i は左から始まり、j は右から始まります 
  10. i < j である間{
  11. i < j && data[j].compareTo(pivotKey) > 0場合
  12. j--;
  13. } // 終了 
  14. もし(i < j){
  15. // ピボット要素より小さい要素を左に移動する 
  16. データ[i] = データ[j];
  17. 私は++;
  18. } // 終了 
  19. i < j && data[i].compareTo(pivotKey) < 0場合
  20. 私は++;
  21. } // 終了 
  22. もし(i < j){
  23. // ピボット要素より大きい要素を右に移動する 
  24. データ[j] = データ[i];
  25. j--;
  26. } // 終了 
  27. } // 終了 
  28. // ピボット要素を正しい位置に移動する 
  29. データ[i] = pivotKey;
  30. // サブリストの前半を再帰的にソートする 
  31. ソート(データ、low、i - 1 );
  32. // サブリストの後半部分を再帰的にソートする 
  33. ソート(データ、i + 1 、高);
  34. } // 終了 
  35. } // ソート終了 
  36. 公共 静的  void main(String[] args) {
  37. // JDK1.5以降では、基本データ型は自動的にボックス化されます 
  38. // intやdoubleなどの基本型のラッパークラスはComparableインターフェースを実装しています 
  39. 比較可能[] c = { 4 9 23 1 45 27 5 2 };
  40. ソート(c, 0 , c.length - 1 );
  41. (比較可能データ: c) {
  42. System.out.println(データ);
  43. }
  44. }
  45. }

クイックソートは現在最も広く使われているソートアルゴリズムです。クイックソートの核心はセグメンテーションアルゴリズムにあり、最も巧妙な部分とも言えます。この記事がお役に立てば幸いです。

【編集者のおすすめ】

  1. 5.11 3行のコードでクイックソート
  2. 12.3.2 タスクスティールに基づくクイックソート
  3. 19.4.2 Parallel_For による並列クイックソート
  4. C# クイックソートの興味深い実装: Haskell から始める

<<:  Java ソートアルゴリズムの概要 (VIII): 基数ソート

>>:  Java ソートアルゴリズムの概要 (VI): ヒープソート

ブログ    

推薦する

AlphaGoの仕組み:マルチエージェント強化学習の詳細な説明

このレビュー記事では、著者はマルチインテリジェンス強化学習の理論的基礎を詳細に紹介し、さまざまなマル...

開発者に人気の機械学習 API 10 選

つい最近まで、人工知能には科学者が白衣を着て研究室で研究を行う必要があると考えられていました。この科...

二足歩行ロボット「キャシー」が機械学習を使って5kmのジョギングを完走

ロボット工学の世界では 4 年というのは長い期間ですが、特にオレゴン州立大学 (OSU) が開発した...

食習慣の変化に伴い、スマートロボットキッチン技術が熱を帯びる

COVID-19パンデミックが続く中、非接触型の食事がますます人気になっています。宅配やテイクアウト...

Google のコード生成システムはプログラマーの半分を「飲み込んだ」のでしょうか?人類は長い間AIに「負けて」きました!

著者: 徐潔成最近、センセーショナルなAlphaGo囲碁ロボットを発売したDeepMindが再び大き...

Zipf 行列分解: 推奨システムにおけるマシュー効果を解決する強力なツール

[[407036]] [51CTO.com からのオリジナル記事]アルゴリズムの公平性は、近年、推奨...

Bespin Global: AI技術を活用してクラウドネイティブのインテリジェントな運用・保守方法を構築

【51CTO.comオリジナル記事】序文最近、Bespin Globalの共同創設者であるBrad ...

新しいAGVロボットナビゲーション技術!屋内ナビゲーション用の新しいロボット フレームワークが登場しました。

移動ロボットは、人間が設計したタスクを完了するために、現実世界の環境を効果的にナビゲートし、周囲の人...

一般開発者もBaidu Brain Industry Application Innovation Challengeに参加して大きな賞金を獲得できる

[51CTO.comからのオリジナル記事] 2018年、人工知能の発展は消費者向け人工知能から企業向...

疫病との戦いに人工知能とビッグデータが爆発的に役立つでしょうか?

[[315014]]新型コロナウイルス感染症の発生と蔓延は、全国の人々の心を動かしました。社会のあ...

...

...

Meituと中国科学技術大学が共同で顔面修復法DiffBFRを提案

ブラインド フェイス リストレーション (BFR) は、低品質の顔画像から高品質の顔画像を復元するこ...

ACM 発表: 2017 年チューリング賞はチップ業界の巨匠 2 名に授与される

米国計算機協会(ACM)は、2017年のチューリング賞を、チップ業界の巨匠2名、スタンフォード大学元...