一般的な基本的なソートアルゴリズムを今回から理解しましょう

一般的な基本的なソートアルゴリズムを今回から理解しましょう

[[382785]]

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

序文

すべてのプログラマーが最初に接触するアルゴリズムはソート アルゴリズムであると私は信じています。ソートはデータ処理と計算において重要な役割を果たしており、ソート アルゴリズムは他のアルゴリズムの基礎となることが多いためです。この記事では、基本的なソート アルゴリズムからアルゴリズムの学習を始めます。

ソートアルゴリズムのテンプレート

始める前に、ソート アルゴリズムの共通テンプレートを定義しましょう。以降のすべてのソート アルゴリズムはこのテンプレートを実装します。

  1. パブリックインターフェースSortTemplate {
  2.  
  3. void sort(Comparable[] 配列);
  4.  
  5. デフォルトvoid print(Comparable[]配列) {
  6. for (比較可能な a : 配列) {
  7. システム.out.print (a + " " );
  8. }
  9. }
  10.  
  11. デフォルトのブール値 less(比較対象 a, 比較対象 b) {
  12. a.compareTo(b) < 0を返します
  13. }
  14.  
  15. デフォルトvoid exch(Comparable[] 配列、 int i、 int j) {
  16. 比較可能なtmp = array[i];
  17. 配列[i] = 配列[j];
  18. 配列[j] = tmp;
  19. }
  20.      
  21. }
  • Comparable: 実装するソート アルゴリズムをより汎用的にし、任意のオブジェクトをソートするために、ここでは Comparable 配列を使用します。
  • ソート: ソートアルゴリズムはそれぞれ異なる方法で実装されるため、サブクラスで独自に実装します。
  • less: a < b の場合に true を返すパブリックメソッドが定義されています
  • exch: 配列内の2つのオブジェクトを交換するために定義されたパブリックメソッド
  • print: データ内の各要素を印刷する

選択ソート

アルゴリズム実装のアイデア:

  • まず配列内の最小の要素を見つけます。
  • 実際には、配列の最初の要素と交換して、 1 つの要素が配置されるようにします。
  • 残りの要素の中から最小の要素を再度見つけ、それを配列の 2 番目の要素と交換し、すべての要素が整列するまでこのプロセスを繰り返します。

コード実装:

  1. パブリッククラスSelectionSortはSo​​rtTemplateを実装します。
  2.  
  3. @オーバーライド
  4. パブリックvoid ソート(比較可能な[] 配列) {
  5. int長さ = 配列.長さ;
  6. ( int i = 0; i < 長さ; i++) {
  7. 整数 最小値= i;
  8. ( int j = i + 1; j < 長さ; j++) {
  9. if (less(配列[j], 配列[ min ])) {
  10. 最小値= j;
  11. }
  12. }
  13. exch(配列、i、 min );
  14. }
  15. }
  16.  
  17. }

入力配列がソートされている場合、選択ソートの実行にはソートされていない場合と同じくらいの時間がかかることがわかります。

N要素の配列の場合、選択ソートを使用する際の時間計算量はO(n2)である。

選択ソートは、移動するデータが最も少ないソートです。スワップの数は、配列のサイズに比例します。N 要素の配列には、N 回のスワップが必要です。

バブルソート

アルゴリズム実装のアイデア:

  • 隣接する 2 つの要素を比較します。最初の要素が 2 番目の要素よりも大きい場合は、2 つの要素の位置を入れ替えます。
  • 最後の要素まで、隣接する要素の各グループに対して同じ操作を実行します。操作が完了したら、最大の要素をランク付けできます。
  • 配列内のすべての要素が整うまでこのプロセスを繰り返します。

コード実装:

  1. パブリッククラスBubbleSortはSo​​rtTemplateを実装します。
  2.  
  3. @オーバーライド
  4. パブリックvoid ソート(比較可能な[] 配列) {
  5. int長さ = 配列の長さ - 1;
  6. ( int i = 0; i < 長さ; i++) {
  7. ( int j = 0; j < 長さ - i; j++) {
  8. if (less(配列[j + 1], 配列[j])) {
  9. exch(配列、j、j + 1);
  10. }
  11. }
  12. }
  13. }
  14.  
  15. }

N要素の配列の場合、バブルソートの時間計算量はO(n2)です。

挿入ソート

ポーカーをプレイしているとき、左側の分類されたカードの適切な位置に各カードを挿入してカードを並べることを想像してください。挿入ソートの考え方は似ている

アルゴリズム実装のアイデア:

  • 最初の要素はデフォルトで最初に順序付けられ、現在のインデックスは 0 から始まります。
  • 現在のインデックス位置を 1 つずつ移動します。現在のインデックス位置の左側の要素は順番になっています。コードを後ろから前に向かってスキャンし、現在のインデックス位置の要素と比較します。
  • 現在のインデックス位置の要素が左側の順序付けられた位置に収まることを確認した後、その位置に挿入します。
  • 現在のインデックス位置の要素がソートされた最後の要素より大きいと判断された場合、現在のインデックス位置は直接後方に移動します。
  • すべての要素が整うまでこのプロセスを繰り返します。

コード実装:

  1. パブリッククラスInsertionSortはSo​​rtTemplateを実装します。
  2.  
  3. @オーバーライド
  4. パブリックvoid ソート(比較可能な[] 配列) {
  5. int長さ = 配列.長さ;
  6. ( int i = 1; i < 長さ; i++) {
  7. for ( int j = i; j > 0 && less(array[j], array[j - 1]); j --) {  
  8. exch(配列、j、j - 1);
  9. }
  10. }
  11. }
  12.  
  13. }

コードの実装から、現在のインデックスの要素が左側の順序付き配列の最後の要素よりも大きい場合、内部ループが直接終了し、ソートする配列に部分的な順序があり、挿入ソート アルゴリズムが非常に高速になることがわかります。

最悪のケースを考えると、入力配列が反転されている場合、挿入ソートの効率は選択ソートと同じで、「時間計算量はO(n2)」です。

シェルソート

挿入ソートは、隣接する要素を交換するだけであり、要素は配列から正しい位置に少しずつしか移動できないため、大規模な順序不同の配列では遅くなります。挿入ソートは、部分的に順序付けられた配列をソートするのに非常に効率的です。

シェルソートは、これら 2 つの特性に基づいて挿入ソートを改良します。

アルゴリズム実装のアイデア

  • まず、サブ配列を分離するためのステップ サイズ h を設定します。
  • 挿入ソートを使用してhサブ配列を個別にソートする
  • hステップサイズを減らし、hステップサイズが1になるまでサブ配列のソートを続けます。
  • ステップサイズが 1 の場合、通常の挿入ソートになるため、配列は順序どおりに並んでいる必要があります。

シェル ソートが効率的な理由は、ソートの開始時に各サブ配列が非常に短く、ソート後にサブ配列が部分的に順序付けられるためです。どちらの状況も挿入ソートに非常に適しています。

コード実装:

  1. パブリッククラス ShellSort は SortTemplate を実装します {
  2.  
  3. @オーバーライド
  4. パブリックvoid ソート(比較可能な[] 配列) {
  5. ギャップ= 1;
  6. int長さ = 配列.長さ;
  7.  
  8. (ギャップ<長さ/3){
  9. ギャップ = 3 * ギャップ + 1;
  10. }
  11.  
  12. ギャップ >= 1 の場合
  13. ( int i = ギャップ; i < 長さ; i++) {
  14. for ( int j = i; j >= gap && less(array[j], array[j - gap]); j -= gap) {
  15. exch(配列、j、j - ギャップ);
  16. }
  17. }
  18. ギャップ = ギャップ / 3;
  19. }
  20. }
  21.  
  22. }

<<:  図解による古典的なプロセススケジューリングアルゴリズム

>>:  自動運転・ホログラム投影!映画に出てくるブラックテクノロジーは私たちからどれくらい遠いのでしょうか?

ブログ    
ブログ    

推薦する

3nmなのに歯磨き粉を絞ってるだけ? A17 Proの実行スコアが公開:CPUマルチコアはわずか3.6%向上

昨日Apple A17 Proが正式リリースされ、3nmプロセスを採用していますが、その性能はどのよ...

スマートフォンアプリケーションにおける人工知能の役割

人工知能がスマートフォンアプリとユーザーエクスペリエンスをどのように変えているのか。進化し続けるテク...

2019年の世界人工知能チップ産業の市場競争状況の分析

1. 世界の人工知能チップ産業の企業概要の分析近年、さまざまな勢力が AIチップに注目しています。参...

...

「機械学習」CNNを徹底理解

[[212238]]前世紀、科学者は視覚神経のいくつかの特性を発見しました。視神経には局所的な知覚が...

C# 遺伝的アルゴリズム学習ノート

次のコードは、C# 遺伝的アルゴリズムを使用して、単純な花の進化シミュレーション プロセスを実装しま...

AIが顧客関係管理を改善する3つの方法

AI には、CRM に関連する手動プロセスから組織を解放し、顧客エンゲージメント、販売分析情報、ソー...

メタヘッドセットが舌トラッキング機能を追加、ネットユーザー衝撃「理由は聞かないし、知りたくもない」

突然でしたね… Meta の MR ヘッドセットは舌を追跡できるようになりました。効果は次のようにな...

...

Python を使用したソーシャル メディア感情分析の入門

[[265146]]自然言語処理の基礎を学び、2 つの便利な Python パッケージを調べます。自...

ソフトウェアテストに AI を統合する 9 つのメリット

[[390945]] [51CTO.com 速訳]人工知能の普及は人々に大きな期待をもたらしました。...

通信産業の発展を後押しし、2つの主要ドローンの価値が強調される

最近、わが国の科学技術分野は新たな躍進を遂げました。ドローンによる「橋渡し」の力を借りて、量子ネット...

ヘルスケアにおける自然言語処理 (NLP) の 8 つの例

翻訳者 | 夏東偉校正 | 梁哲、孫淑娟医療においては、データは患者の健康記録、医師の指示、処方箋か...

将来、AIと競争して仕事を得るための16の実践的なヒント

[[256943]]現在、多くの企業がすでに人工知能と機械学習を活用しており、これらのテクノロジーの...