プログラマーが知っておくべきトップ10のプログラミングアルゴリズム

アルゴリズム(アルゴリズム)とは、問題解決スキームの正確で完全な説明を指します。これは、問題を解決するための一連の明確な指示です。アルゴリズムは、問題を解決するための戦略メカニズムを説明する体系的な方法を表します。言い換えれば、特定の標準入力に対して限られた時間内に必要な出力を取得することが可能です。アルゴリズムに欠陥があるか、特定の問題に適していない場合、このアルゴリズムを実行しても問題は解決しません。アルゴリズムが異なれば、同じタスクを実行するために異なる時間、スペース、または効率を使用する場合があります。アルゴリズムの長所と短所は、空間の複雑さと時間の複雑さによって測定できます。

アルゴリズムの命令は、実行時に初期状態と(場合によっては空の)初期入力から開始し、一連の有限で明確に定義された状態を経て、最終的に出力を生成し、最終状態で停止できる計算について説明します。ある状態から別の状態への移行は必ずしも確実ではありません。ランダム化アルゴリズムを含む一部のアルゴリズムには、いくつかのランダム入力が含まれています。

アルゴリズム1:クイックソートアルゴリズム

クイックソートは、TonyHallによって開発されたソートアルゴリズムです。平均して、n個のアイテムをソートするにはΟ(n log n)の比較が必要です。最悪の場合、Ο(n2)の比較が必要ですが、この状況は一般的ではありません。実際、クイックソートは通常、他のΟ(n log n)アルゴリズムよりも大幅に高速です。これは、その内部ループをほとんどのアーキテクチャで効率的に実装できるためです。

Quicksortは、分割と征服の戦略を使用して、リストを2つのサブリストに分割します。

アルゴリズムの手順:

1シーケンスから要素を選択し、それを「ピボット」と呼びます。

2シーケンスを並べ替えると、ベンチマーク値よりも小さいすべての要素がベンチマークの前に配置され、ベンチマーク値よりも大きいすべての要素がベンチマークの後ろに配置されます(同じ番号をどちらの側にも配置できます)。パーティションが終了した後、ベンチマークはシーケンスの途中にあります。これは、パーティション操作と呼ばれます。

3参照値よりも小さい要素のサブシーケンスと、参照値よりも大きい要素のサブシーケンスを再帰的にソートします。

再帰の一番下のケースは、シーケンスのサイズが0または1である、つまり、常にソートされていることです。再帰的ですが、このアルゴリズムは常に終了します。これは、各反復で、少なくとも1つの要素が最後の位置に配置されるためです。


アルゴリズム2:ヒープソートアルゴリズム

ヒープソートとは、ヒープのデータ構造を使用して設計されたソートアルゴリズムを指します。スタッキングは、完全なバイナリツリーを近似する構造であると同時に、スタッキングの性質を満たします。つまり、子ノードのキーまたはインデックスは、常にその親ノードよりも小さい(または大きい)です。

ヒープソートの平均時間の複雑さはΟ(nlogn)です。

アルゴリズムの手順:

ヒープを作成するH [0..n-1]

ヘッド(最大)とテールを交換します

3.ヒープのサイズを1減らし、shift_down(0)を呼び出します。目的は、新しい配列の最上位データを対応する位置に調整することです。

4.パイルのサイズが1になるまで、手順2を繰り返します。

アルゴリズム3:マージソート

マージソート(マージソート、台湾翻訳:マージソート)は、マージ操作に基づく効果的なソートアルゴリズムです。このアルゴリズムは、Divide andConquerの非常に典型的なアプリケーションです。

アルゴリズムの手順:

1.サイズが2つのソートされたシーケンスの合計になるようにスペースを申請します。このスペースは、マージされたシーケンスを格納するために使用されます。

2. 2つのポインターを設定します。初期位置は、ソートされた2つのシーケンスの開始位置です。

3. 2つのポインターが指す要素を比較し、マージスペースに配置する比較的小さな要素を選択して、ポインターを次の位置に移動します。

4.ポインタがシーケンスの最後に到達するまで、手順3を繰り返します。

5.別のシーケンスの残りのすべての要素をマージされたシーケンスの最後に直接コピーします

アルゴリズム4:バイナリ検索アルゴリズム
バイナリ検索アルゴリズムは、順序付けられた配列内の特定の要素を見つけるための検索アルゴリズムです。検索プロセスは、配列の中央の要素から開始します。中央の要素が検索対象の要素である場合、検索プロセスは終了します。特定の要素が中央の要素よりも大きいか小さい場合は、配列の半分の中央の要素よりも大きいか小さいものを検索します。 、そして最初と同じように真ん中の要素から比較を開始します。特定のステップで配列が空の場合は、配列が見つからないことを意味します。この検索アルゴリズムは、比較するたびに検索範囲を半分に減らします。ハーフサーチは毎回サーチエリアを半分に減らし、時間の複雑さはΟ(logn)です。

アルゴリズム5:BFPRT(線形検索アルゴリズム)

BFPRTアルゴリズムによって解決される問題は非常に古典的です。つまり、n個の要素のシーケンスからk番目に大きい(k番目に小さい)要素を選択します。巧妙な分析により、BFPRTは、最悪の場合でも線形の時間の複雑さを保証できます。このアルゴリズムの考え方は、クイックソートの考え方と似ています。もちろん、最悪の場合でもアルゴリズムをo(n)の時間の複雑さに到達させるために、5人のアルゴリズム作成者が微妙なプロセスを実行しました。

アルゴリズムの手順:

1. n個の要素を5つのグループ(上限)に分割します。

2.各グループの中央値を取得し、挿入ソートなどの任意のソート方法を使用します。

3.選択アルゴリズムを再帰的に呼び出して、前の手順ですべての中央値の中央値を見つけ、それをxに設定します。中央値が偶数の場合は、最小のものを選択するように設定します。

4. xを使用して配列を分割し、x以下の数値をkとして設定し、xより大きい数値をnkとして設定します。

5. i == kの場合、xを返します。i<kの場合、xより小さい要素の中からi番目に小さい要素を再帰的に見つけます。i> kの場合、xより大きい要素の中からi番目に小さい要素を再帰的に見つけます。

終了条件:n = 1の場合、小さい要素iが返されます。
アルゴリズム6:DFS(深度優先検索)

Depth-First-Searchは一種の検索アルゴリズムです。それは木の深さに沿って木のノードを横断し、木の枝を可能な限り深く検索します。ノードvのすべてのエッジが探索されると、検索はノードvが見つかったエッジの開始ノードに戻ります。このプロセスは、ソースノードから到達可能なすべてのノードが見つかるまで続きます。まだ検出されていないノードがある場合は、それらの1つをソースノードとして選択し、上記のプロセスを繰り返します。すべてのノードにアクセスするまで、プロセス全体が繰り返されます。DFSはブラインド検索です。

深度優先検索はグラフ理論の古典的なアルゴリズムです。深度優先検索アルゴリズムは、ターゲットグラフの対応するトポロジカルソートテーブルを生成でき、トポロジカルソートテーブルは、最大パス問題など、多くの関連するグラフ理論の問題を簡単に解決できます。ヒープデータ構造は通常、DFSアルゴリズムの実現を支援するために使用されます。

深度優先トラバーサルグラフアルゴリズムの手順:

1.頂点vにアクセスします。

2. vの未訪問の隣接ポイントから順番に、グラフ上で深度優先トラバーサルを実行します。vへのパスを持つグラフ内の頂点が訪問されるまで。

3.グラフ内に未訪問の頂点から開始して、現時点で訪問されていない頂点がある場合、グラフ内のすべての頂点が訪問されるまで、深度優先トラバーサルが繰り返されます。

上記の説明は、より抽象的な場合があります。次に例を示します。

DFSは、グラフ内の特定の開始頂点vにアクセスした後、vから開始し、隣接する頂点w1のいずれかにアクセスします。次に、w1から開始して、w1に隣接しているがアクセスされていない頂点w2にアクセスし、次にw2から開始して続行します。同様の訪問...すべての隣接する頂点が訪問された頂点uに到達するまで、この方法で続行します。

次に、一歩下がって、前回アクセスしたばかりの頂点に移動し、アクセスしていない隣接する頂点が他にあるかどうかを確認します。ある場合は、この頂点にアクセスし、次にこの頂点から先に進んで上記と同様のアクセスを実行します。ない場合は、1ステップ戻って検索します。接続されたグラフのすべての頂点にアクセスするまで、上記のプロセスを繰り返します。
アルゴリズム7:BFS(幅の最初の検索)

Breadth-First-Searchは、グラフ検索アルゴリズムです。簡単に言えば、BFSはルートノードから開始し、ツリー(グラフ)の幅に沿ってツリー(グラフ)のノードをトラバースします。すべてのノードにアクセスすると、アルゴリズムは停止します。BFSもブラインド検索です。キューデータ構造は通常、BFSアルゴリズムの実現を支援するために使用されます。

アルゴリズムの手順:

1.最初にルートノードをキューに入れます。

2.キューから最初のノードを取り出し、それがターゲットであるかどうかを確認します。

ターゲットが見つかった場合、検索は終了し、結果が返されます。

それ以外の場合は、チェックされていない直接の子ノードがすべてキューに追加されます。

3.キューが空の場合は、画像全体がチェックされていることを意味します。つまり、画像内で検索するターゲットがありません。検索を終了し、「ターゲットが見つかりません」を返します。

4.手順2を繰り返します。

アルゴリズム8:Dijkstraアルゴリズム

Dijkstraのアルゴリズム(Dijkstraのアルゴリズム)は、オランダのコンピューター科学者AzchelDijkstraによって提案されました。Dijkstraアルゴリズムは、幅優先検索を使用して、負でない重みを持つ有向グラフの単一ソースの最短パス問題を解決し、最終的に最短パスツリーを取得します。このアルゴリズムは、ルーティングアルゴリズムで、または他のグラフアルゴリズムのサブモジュールとしてよく使用されます。

アルゴリズムの入力には、加重有向グラフGとGのソース頂点Sが含まれます。VがGのすべての頂点のセットを表すとします。各グラフのエッジは、2つの頂点によって形成される要素の順序付けられたペアです。(u、v)は、頂点uからvに接続するパスがあることを意味します。GのすべてのエッジのセットをEで表し、エッジの重みは重み関数w:E→[0、∞]で定義されます。したがって、w(u、v)は、頂点uから頂点vまでの非負の重みです。エッジの重みは、2つの頂点間の距離として想像できます。任意の2点間のパスの重みは、パス上のすべてのエッジの重みの合計です。Vに頂点sとtがあることを知っていると、Dijkstraのアルゴリズムは、sからtまでの重みが最も小さいパス(たとえば、最短パス)を見つけることができます。このアルゴリズムは、頂点sからグラフ内の他の頂点への最短パスを見つけることもできます。負の重みのない有向グラフの場合、Dijkstraのアルゴリズムは、現在知られている最速の単一ソース最短パスアルゴリズムです。

アルゴリズムの手順:

1.初期時間S = {V0}、T = {残りの頂点}、Tの頂点に対応する距離値

<v0、vi>がある場合、d(V0、Vi)は<v0、vi>アークの重みです。

<v0、vi>がない場合、d(V0、Vi)は∞です。

2. SではなくTからの距離値が最小の頂点Wを選択し、Sを追加します。

3.残りのTの頂点の距離値を変更します。Wが中間頂点として追加され、V0からViまでの距離値が短縮されている場合は、この距離値を変更します。

すべての頂点がSに含まれるまで、つまりW = Viになるまで、上記の手順2と3を繰り返します。

アルゴリズム9:動的プログラミングアルゴリズム

動的プログラミングは、元の問題を比較的単純なサブ問題に分解することによって複雑な問題を解決するために、数学、コンピューターサイエンス、および経済学で使用される方法です。動的プログラミングは、多くの場合、重複するサブ問題と最適なサブ構造の問題に適しています。動的プログラミングの時間のかかる方法は、多くの場合、単純なソリューションの方法よりもはるかに少ないです。

動的プログラミングの背後にある基本的な考え方は非常に単純です。大まかに言えば、特定の問題を解決したい場合は、そのさまざまな部分(つまり、サブ問題)を解決してから、サブ問題の解決策をマージして、元の問題の解決策を取得する必要があります。通常、多くのサブ問題は非常に似ています。このため、動的プログラミング方法では、各サブ問題を1回だけ解決しようとするため、計算量が削減されます。特定のステータ問題の解決策が計算されると、記憶されて保存されるため、次回も同じサブ問題が必要になります。解決するときは、テーブルを直接確認してください。このアプローチは、繰り返されるサブ質問の数が入力のサイズに対して指数関数的に増加する場合に特に役立ちます。

動的プログラミングに関する最も古典的な問題は、ナップザックの問題です。

アルゴリズムの手順:

1.最適な下部構造のプロパティ。問題の最適解に含まれる副問題の解も最適である場合、その問題は最適な部分構造の特性を持っている(つまり、最適化の原則を満たしている)と言えます。最適な下部構造のプロパティは、動的プログラミングアルゴリズムが問題を解決するための重要な手がかりを提供します。

2.サブ問題の重複する性質。サブ問題の重複する性質は、再帰的アルゴリズムを使用して問題を上から下に解決する場合、毎回生成されるサブ問題が必ずしも新しい問題であるとは限らず、一部のサブ問題が複数回繰り返されることを意味します。動的プログラミングアルゴリズムは、このサブ問題の重複する性質を利用して、各サブ問題を1回だけ計算し、その計算結果をテーブルに保存します。計算されたサブ問題を再度計算する必要がある場合は、テーブルのみに保存します。結果を確認するだけで、効率が向上します。
アルゴリズム10:ナイーブベイズ分類アルゴリズム

ナイーブベイズ分類アルゴリズムは、ベイズの定理に基づく単純な確率分類アルゴリズムです。ベイジアン分類の基礎は確率論的推論です。これは、さまざまな条件の存在が不確実であり、それらの発生の確率のみがわかっている場合に、推論および意思決定タスクを完了する方法です。確率論的推論は決定論的推論に対応します。素朴なベイズ分類器は、独立した仮説に基づいています。つまり、サンプルの各機能は他の機能に関連していないと想定されています。

Naive Bayes分類器は、正確な自然確率モデルに依存して、監視対象の学習サンプルセットで非常に優れた分類結果を取得します。多くの実際のアプリケーションでは、ナイーブベイズモデルのパラメーター推定は最大尤度推定法を使用します。言い換えると、ナイーブベイズモデルはベイズ確率またはベイズモデルなしで機能します。

クイックソート、マージソート、ヒープソート

では、実際のアプリケーションでどのように選択するのでしょうか?これらの選択基準があります:

    nが小さい場合は、挿入ソートと単純選択ソートを使用します。直接挿入ソートは、単純な選択ソートよりも多くのレコード移動操作を必要とするため、レコード自体の情報量が比較的多い場合は、単純選択ソートを使用することをお勧めします。
    ソートするシーケンスが基本的に正しい場合は、直接挿入ソートまたはバブルソートを使用できます
    。nが大きい場合は、高速ソート、ヒープソート、マージなど、時間の複雑さが最も低いアルゴリズムを使用する必要があります。

        細分化に関しては、データがランダムに分散されている場合、高速ソートが最適です(これは、前のブログ投稿で説明した高速ソートのハードウェア最適化に関連しています)。
        ヒープ行に必要な補助スペースは1つだけであり、高速ソートはありません。悪い場合は、
        高速ソートとヒープソートの両方が不安定です。安定性が必要な場合は、マージを使用できます。直接挿入ソートとマージを組み合わせることもできます。最初に直接挿入を使用して順序付けられたフラグメントを取得してからマージすると、得られる結果も安定します。直接挿入が安定しているため
 

おすすめ

転載: blog.csdn.net/wangletiancsdn/article/details/105163503