導入プログラマーとして、上位 10 のソート アルゴリズムは必須であり、すべての資格のあるプログラマーが習得する必要があります。また、クイック ソートやマージ ソートなどの一般的なアルゴリズムについては、アルゴリズムのパフォーマンスと複雑さの習得を必要とする、より詳細な質問を受ける場合があります。 Java とデータ構造およびアルゴリズムに関する責任あるブロガーとして、bigsai はこの点に関して読者に抜け穴を絶対に残しません。この記事を読んでいただければ、最も一般的な 10 個のソート アルゴリズムを紹介し、簡単に習得できるようにお手伝いします。 まず、ソートに関して言えば、ほとんどの人にとってソートの概念はバブル ソートまたは JDK の Arrays.sort() のままです。上位 10 位のソート アルゴリズムは言うまでもなく、さまざまなソート アルゴリズムを手書きすることは多くの人にとって贅沢です。しかし、幸運なことに、あなたはこの記事に出会いました。 ソートの分類には、主に、複雑性、内部と外部、比較的次元と非比較的次元などのさまざまな次元があります。私たちがよく話題にする上位 10 のソート アルゴリズムは、内部ソートです。これらは、「比較と非比較」の次元に基づくソート タイプの 2 つのカテゴリに分類されます。
バブルソートバブル ソート (バブル ソートとも呼ばれる) は、交換ベースの典型的なソート アルゴリズムであり、クイック ソートの考え方の基盤となっています。バブル ソートは、時間計算量が O(n^2) の安定したソート アルゴリズムです。基本的な考え方は、「ループを複数回実行し、そのたびに大きな要素を前から後ろへ移動し、そのたびに最大 (最小) 要素を決定し、複数回実行した後にソートされたシーケンスに到達する」というものです (または、小さな要素を後ろから前へ移動します)。 具体的なアイデアは(大きな要素を後ろに調整する)です:
たとえば、 実装コードは次のとおりです。
クイックソートクイックソートはバブルソートの改良版であり、再帰的な分割統治アプローチを使用して問題を解決します。バブルソートと比較すると、クイックソートは不安定なソートです。最悪の時間計算量は O(n^2)、平均的な時間計算量は O(nlogn)、最良の時間計算量は O(nlogn) です。 クイックソートの基本的な考え方は次のとおりです。
実装コードは次のとおりです。
挿入ソート直接挿入ソート直接挿入ソートは、すべてのソートアルゴリズムの中で最も単純なソート方法の 1 つです。学生時代と同じように、私たちは前から後ろに背の高い順に並んでいました。ですから、身長のバラバラな人たちの集団の中では、先頭の人から始めて、自分より背の高い人が前にいたら、すぐに適切な位置に身を置きます。キュー全体の順序は、「キューの最後のものが挿入されるまで」のみ維持されます。 直接挿入ソートのトラバーサル比較の時間計算量は毎回 O(n) であり、交換の時間計算量も毎回 O(n) であるため、n 回の合計時間計算量は O(n^2) です。バイナリ挿入を O(nlogn) に最適化できるかどうか疑問に思う人もいるかもしれません。答えは「いいえ」です。バイナリ検索では、検索の複雑さを毎回 O(logn) までしか減らすことができませんが、挿入時間の複雑さは毎回 O(n) なので、合計時間複雑さレベルは依然として O(n^2) です。 挿入ソートの具体的な手順は次のとおりです。
実装コードは次のとおりです。
シェルソート直接挿入ソートは O(n^2) なので、データ量が多い場合やデータの移動回数が多すぎる場合には効率が悪くなります。多くのソート方法は、シーケンスを分割してから結合しようとします。シェルソートは、「データ量と順序」という 2 つの側面を考慮してアルゴリズムを設計し、特別な方法で前処理を実行します。できるだけ小さいものを前に、大きいものを後ろにして、グループ化の計算を数回実行し、最後のグループは完全な直接挿入ソートになります。
このような挿入を行うたびにシーケンスの順序が整えられるため、わずかに順序付けられたシーケンスに対して直接挿入ソートを実行してもコストはかかりません。したがって、合併が完了すると、小さい方が前に出て、大きい方が後ろに来ることになり、コストはどんどん小さくなります。このように、シェルソートでは挿入ソートに比べて多くの時間を節約できます。 実装コードは次のとおりです。
クラスソートを選択単純な選択ソート選択ソートはシンプルで直感的なソートアルゴリズムです。仕組み: まず、ソートされていないシーケンス内の最小 (最大) の要素を見つけて、ソートされたシーケンスの先頭に格納します。次に、残りのソートされていない要素から最小 (最大) の要素を探し続け、それを「ソートされたシーケンスの末尾」に配置します。すべての要素がソートされるまでこれを繰り返します。 実装コードは次のとおりです。
ヒープソートは、まずヒープを基準に行われます。ヒープは完全な二分木です。まず、大きなルートヒープと小さなルートヒープを理解する必要があります。完全な二分木のすべてのノードは、その子ノードよりも大きい (または小さい) ため、ここでは 2 つのケースがあります。
ヒープソートでは、まず「ヒープを構築」し、次にそれを調整します。バイナリ ツリー (配列表現) の場合、 「最初の非リーフ ノード」から始めて、下から上に調整し、前方に調整します。調整のルールは次のとおりです。 ヒープ構築は、時間計算量が O(n) のプロセスです。ヒープ構築後、ヘッドソートを実行する必要があります。配列を指定してヒープを作成する (createHeap) ① 現在のノードとその子がヒープの特性を維持できるように、最初の非リーフノードからスワップダウン(shiftDown)の判断を開始します。 ②ただし、通常のノードの交換では問題ないかもしれません。交換によって子ヒープ構造の特性が破壊される場合は、交換したノードを再び停止するまでシフトダウンする必要があります。 ヒープが構築され、最初の最上位要素が最小 (最大) として取得されます。残りの左と右の子はヒープのプロパティ値を満たしていますが、最上位要素が欠落しています。子を上に移動すると、移動される要素が多すぎてヒープ構造が破壊される可能性があります。 ①最後の要素を最初に置くだけです。このように、スワップダウン(shiftDown)の判定だけ行えば良いのですが、このときヒープ全体のサイズが変わっていることに注意が必要です。放棄した位置を論理的に利用することはないので、関数設計時にはヒープサイズのパラメータが必要になります。 ②ヒープ内のすべての要素が取得されるまで、上記の手順を繰り返します。 ヒープ アルゴリズムの複雑さの分析では、ヒープ構築の時間計算量は以前は O(n) でした。ヒープの先頭が削除されるたびに、下方向にスワップする必要があり、それぞれの最悪数は logn になります。これにより、複雑さは O(nlogn) になります。合計時間複雑さは O(n)+O(nlogn)=O(nlogn) です。 実装コードは次のとおりです。
マージクラスソートマージソートでは、通常はマージソートについてのみ説明しますが、マージソートは双方向マージと多方向マージにも分けられます。ここでは、双方向マージソートについてさらに詳しく説明し、再帰的に実装します。 マージソートマージとクイック ソートはどちらも「分割統治アルゴリズムに基づいています」 。分割統治アルゴリズムは実際には多くの用途があり、多くの分割統治アルゴリズムは再帰を使用しますが、実際には「分割統治と再帰は異なるものです」 。分割統治とは分割統治を意味し、再帰的に実装することも、非再帰的な方法でプロセス全体を自分で走査することによって実装することもできます。マージソートは、まず問題をコストの低いサブ問題に分解し、次にコストの低いサブ問題をマージしてソートを完了します。 マージの背後にある考え方は次のとおりです。
O(n) プロセスに統合: 実装コードは次のとおりです。
バケットソートバケット ソートは、スペースと時間をトレードするソートです。バケット ソートで重要なのは、そのアイデアであり、具体的な実装ではありません。最適な時間計算量は線形 O(n) かもしれません。バケット ソートは、比較ベースのソートではなく、分散ベースのソートです。バケットソートは文字通り次のことを意味します:
バケットソートの考え方は、「ソートするシーケンスを複数のバケットに分割し、各バケット内の要素を個別にソートする」というものです。もちろん、バケットソートのスキームは特定のデータに関連しています。バケットソートは比較的広い概念であり、カウントソートは特別なバケットソートです。基数ソートもバケットソートに基づいています。データが均等に分散され、各バケット要素が 1 に近づくと、時間計算量は O(n) に達する可能性があります。ただし、データ範囲が大きく、比較的集中している場合は、バケットソートの使用は適していません。 単純なバケットソートを実装します。
カウントソートカウント ソートは特殊なバケット ソートです。各バケットのサイズは 1 です。各バケットはリストで表されなくなり、通常はカウントに値を使用します。 特定のアルゴリズムを設計するときは、まず最小値 min を見つけ、次に最大値 max を見つけます。次に、この間隔サイズの配列を作成し、最小位置からカウントを開始すると、スペースを最大限に圧縮して、スペースの利用効率を向上させることができます。
基数ソート基数ソートは、理解するのは簡単ですが、実装 (最適化) が難しいアルゴリズムです。基数ソートはカードソートとも呼ばれます。基数ソートの原理はカウンティングソートを複数回使うことですが(カウンティングソートは特殊なバケットソートです)、これまでの普通のバケットソートやカウンティングソートと異なるのは、 「基数ソートは全体をバケットに割り当てるのではなく、それ自体を個々の要素に分割し、各要素を順にバケットに割り当てて順番に集めていく」という点です。前から後ろへ、または後ろから前へという順番で各位置を割り当てて集めていくと、順序のあるシーケンスが得られます。 ソートが数値型の場合、このバケットには 0 から 9 までの数字のみを含める必要がありますが、文字型の場合は ASCII の範囲に注意する必要があります。 このような状況に遭遇した場合、基数ソートの考え方は非常にシンプルです。934、241、3366、4399の基数ソートのプロセスを例に挙げてみましょう。最初は、各桁に応じて割り当てと収集を行います。 割り当てと収集は両方とも順序どおりです。2 回目の割り当てと収集は、10 の位に基づいて行われます。今回は、1 回目の割り当てと収集が 1 の位に基づいているため、1 の位と 10 の位だけを見ると、すべての数字が順序どおりになっています。 3回目は百の位を分配して集める時間です。この時間以降は百の位以下が順番になります。 最後に処理するときに、千の位のいくつかの桁にゼロを埋め込む必要があります。これが完了すると、最後の千の位とそれ以降の桁が整列し、シーケンス全体がソートされます。 簡単な実装コードは次のとおりです。
もちろん、等長文字列と不等長文字列、1次元配列の最適化など、学ぶべき基数ソートの実装は様々あります。詳細については、公式アカウントの他の記事を参照してください。 今回はトップ10ランキングをざっくりと振り返りました。皆さんもなんとなくわかっていただけるかと思います!アルゴリズムの概要については、不必要な労力を避けるために、次の表を共有します。
|
<<: 劉烈宏:中国の中核人工知能産業の規模は今年上半期に770億元に達した
>>: マイクロソフトのオープンソースAIツールが古い写真に新たな命を吹き込む
コンピュータサイエンスとエレクトロニクスの急速な発展により、顔認証は現在、指紋に次いで世界第2位の市...
機械学習によってもたらされたあらゆる破壊的技術の中でも、コンピュータービジョンの分野は業界関係者と学...
2014年、日本のソフトバンクモバイルストアに新たな仲間が加わった。それは、人の表情や声のトーンを...
人口減少と人件費の高騰が進む中、ロボットは産業構造改革の中核となっている。ロボットが産業のアップグレ...
1. 現状と問題点1. 現状と問題点Cloud Music データ ウェアハウス プラットフォームは...
この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI)より許可を得て転載...
生成アルゴリズム、事前トレーニング済みモデル、マルチモーダルなどの技術の累積的な統合と反復を経て、人...
[[279165]]今日、認知学習はかつてないほど普及しています。一般的に言えば、認知学習と認知コ...
[51CTO.com クイック翻訳]現在の世界は、コンクリートやアスファルトでできた巨大な迷路のよう...
自動化技術は現在あらゆる業界に浸透しつつあり、これはサプライチェーンにおいて特に顕著です。実際、自動...
AI は、私たちが行うほぼすべての方法を変えています。私たちが行くところすべてで、かつては人間が行っ...