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

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

[[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. }

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

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

ブログ    

推薦する

...

AIは大学入試で高得点のエッセイを書けるようになったが、小説を書くにはまだ遠い

イベントレビュー大学入試中国語テストが終了してすぐに、大学入試作エッセイのテーマが話題になりました。...

新しい問題と古い問題の組み合わせは、個人情報保護に新たな課題をもたらします。

宅配ラベルのプライバシー漏洩、APPからの過度な権利要求、個人情報の違法収集・利用などの問題が依然と...

LLM評価レビュー論文が出版され、3つの側面から包括的にまとめられ、データベースも掲載されている

大規模言語モデル (LLM) は、学界や産業界から幅広い注目を集めています。有用な LLM を開発す...

...

...

百度の自動運転技術は掘削機の運転を熟練ドライバーと同等の効率化に導く

海外メディアのTech Xploreによると、百度の研究ロボット工学・自動運転研究所(RAL)とメリ...

AI はその「創造物」に対して創造的権利を有するのでしょうか?人民日報:いいえ

AI技術の発展に伴い、AIの創作への参加も魅力的なハイライトとなっています。そこで疑問なのが、AI ...

IoT と AI を組み合わせたユースケースにはどのようなものがありますか?

モノのインターネットは現代のビジネスと経済を急速に変革しています。この革新的なテクノロジーにより、膨...

NetEase はデータ指標の異常をどのように検出し、診断するのでしょうか?

1. 背景指標はビジネスと密接に関係しており、その価値は、問題点やハイライトを発見し、タイムリーに...

2018年のAI革命で何が起こったか、何が起こらなかったか

[[253051]] 2018 年を振り返ると、人工知能はデジタル分野で急速な成長を続け、あらゆる業...

人工知能の時代では、次の7つの重要な要素を念頭に置く必要があります

政府は、他の経済的、社会的進歩と同様に、AI とデータの競争力を重視すべきです。研究への投資や技術リ...

Sparkに代わると期待されるリアルタイム機械学習フレームワークRay

新しいプロジェクトは、Python で記述された機械学習アプリケーションをサポートするために使用でき...

...