私はデータ構造で優れたオンラインコースを探していましたが、Googleはアルゴリズムコースの結果も返すことがわかりました。
このコースでは、アルゴリズム設計のいくつかの基本原則を学びます:分割統治法、グラフアルゴリズム、実用的なデータ構造(ヒープ、ハッシュテーブル、検索ツリー)、ランダム化されたアルゴリズムなど。 [ソース]
そして
このクラスの終わりまでに、グラフおよびその他の重要なデータ構造の新しいアルゴリズムを考案し、これらのアルゴリズムの効率を評価するために必要な主要な概念を理解します。 [ソース]
そして
このコースでは、計算問題の数学的モデリングを紹介します。一般的なアルゴリズム、アルゴリズムのパラダイム、およびこれらの問題を解決するために使用されるデータ構造について説明します。 [ソース]
私の質問は次のとおりです。アルゴリズムとデータ構造は密接にリンクされていますか?つまり、それらは一緒に理解されなければならないのですか、それとも1つのトピックが他のトピックよりも基礎的ですか?
編集:この質問を閉じることに投票する人のために、なぜ、そしておそらくこの問題を改善する方法を教えていただけますか?正しい質問をすることを学ぶことは、教育プロセスの一部です。
あらゆる種類の混合物が存在します。アルゴリズムに関連付けられていないデータ構造、アルゴリズム(実際の)データ構造を必要としないアルゴリズムがありますが、ほとんどの場合、2つは1つのパッケージに入っています。
編集: @Dovalが正しく指摘したように、データ構造自体には、関連付けられている操作はありません。データ構造とアルゴリズムを組み合わせるという行為は、抽象的なデータ型を形成します。
たとえば、適切にPoint
と呼ばれる、2次元座標を格納するためのデータ構造を考えます。ポイントに対して実行するアルゴリズムに関しては何もありません。それは実際にはx
およびy
値のコンテナーにすぎません。もちろん、このデータ構造を使用して、あらゆる種類のアルゴリズム(距離計算、凸包、何を持っているか)をその上に追加できるようになりました。
多くのデータ構造を考えることができます。これらは単に個々のデータの蓄積です。これらは実際には頻繁に発生しますが、それから学ぶことは何もないため、それらは優れた教材にはなりません。一度理解すれば、単一のデータ項目を新しいデータ構造に蓄積できることを学びます(何を学ぶかなど)上記のPoint
の例の後、Point3D
と呼ばれるすばらしいデータ構造を提供すると、3次元空間に対して同じことができますか?)
「本物」、明らかに興味深いアルゴリズムはすべて整数やブール値などのプリミティブデータ型を必要とし、このコンテキストではこれらをデータ構造と見なしたくないためです。上記と同様に、これらのアルゴリズムは通常、かなり単純なものです。特に、データ構造に入るので、次のような複雑な状態にはなりません(次のセクションを参照)。
そのようなアルゴリズムの例は、2つの数値の最大公約数の計算です。ユークリッドのgcdのアルゴリズムは、実際には2つの整数を保持して操作するだけで十分です。
しかし、物事がもっと面白くなり始めたら、すぐに抽象データ型の世界に入ります。たとえば、エラトステネスのふるいは配列に基づいています。配列がまだプリミティブであるかどうか、または実際には、整数がまだデータ構造ではないかどうかについて議論することができます。どちらにしても、データ構造なしで完全に存在するアルゴリズムは、たとえ孤立した存在を受け入れたとしても、かなり退屈です。
これらは興味深いものですが、2つの非常に異なる理由があります。通常、これらは2つの方向からアプローチできます。最初にデータ構造、または最初にアルゴリズムです。
抽象データ型はデータ構造+アルゴリズム/操作の組み合わせによって定義されますが、多くの場合、これらのどちらか一方に焦点を当ててそれらを表示し、もう一方をイネーブラーと見なします。
抽象データ型を使用します。これは使用方法はかなり単純ですが、内部で機能させるために多少複雑なアルゴリズムを伴います。たとえば、HashMap
を使用するのは簡単ですが、気の利いたハッシュ関数を使用し、内部でのハッシュの衝突を処理します。それでも、ユーザーとしてのあなたの視点からは、あなたのために何かをするものではなく、あなたのためにデータを保持するものとしてそれを気にします。
以下の最後のグループとは対照的に、これらのデータ構造はユーザーにこれらのアルゴリズムを公開しません。 HashMap
s内部ハッシュ関数を使用できるようにするために、それについて知っている必要も、気にする必要もありません。 (ただし、効果的に使用するには、これらのことを知りたい場合があります。)
もう1つの方向は、単純に使用できるようにしたいが、意図したとおりに機能させるために内部的にデータ構造が必要なアルゴリズムがあることを意味します。例としては、バイナリスペースパーティショニング(BSP)アルゴリズムがあります。これは、特定のクエリポイントに最も近い多数のポイントセットから2次元のPoint
を要求するだけです。ただし、実際にアルゴリズムを作成するには、内部にツリー構造(および距離計算などの追加のアルゴリズム)が必要です。
一般に、このグループのアルゴリズムは、内部状態の表現に関連するデータ構造を使用していると言えます。このアルゴリズムのグループは最も多様であり、この一般的なスキームに適合する多くの異なるアルゴリズムが見つかると私は主張します。観点に関しては、これらは私たちのために何かを行う(例:並べ替え)ので、データ保持部分をあまり気にしないので、これらは興味深いものであると思います。
最後に、データ構造があります。これは、データ構造に直接対応するアルゴリズムに非常に密接に関連しています。典型的な例はバイナリツリーです。これを使用して意味のある何かをしたい場合、ツリーウォーキングアルゴリズムのトピックを強制します(深さ優先、幅優先など)。
これらの場合、結果の抽象データ型のビューの焦点を時々変更します。ときどきツリーの構造を気にし、数分後にそれに対して検索操作を実行できることを気にし、次にノードを削除することに疑問を持ち、構造がその後どのように見えるかについてすぐに気にします。これは上記の他のセクションにも当てはまりますが、たとえばMap
との間でデータを格納/取得するとき、またはリンクされたリストをソートします。
データ構造は、アルゴリズムの詳細に影響を与えることがよくあります。このため、この2つはしばしば密接に関係しています。
たとえば、芝生を切るアルゴリズムを考えてみましょう。芝生の刈り取り方は、実際の芝生の構造に影響される可能性があります。密集した郊外の小さな家に住んでいて、芝生が数メートル四方の小さな長方形である場合は、トラクター/乗用芝刈り機ではなく、プッシュ芝刈り機で芝生を切りたいと思うでしょう。芝生に数エーカーの平坦な牧草地が含まれる場合、プッシュ芝刈り機ではなく乗用芝刈り機が優先される場合があります(いずれの芝刈り機でも最終的には作業が完了する場合があります)。あなたの芝生が大きな平坦な領域のある数エーカーの土地を含み、少数の小さな丘と多くの樹木が含まれる場合、乗用芝刈り機とプッシュ芝刈り機、またはその他の芝生の両方を含む芝生を切断するためのより興味深いアルゴリズムを開発することができます切削技術。
ただし、最終的には、データの構造が、アルゴリズムの開発方法(または使用するアルゴリズム)の決定に大きな影響を与える可能性があります。このため、2つのトピックはしばしば関連しています。
逆もまた同様です。使用したいアルゴリズムが、アルゴリズムをサポートするために開発したデータ構造に(少なくとも計算の開始時に)影響を与える場合があります。たとえば、配列リストからリンクされたリストのアイデアに、そして最終的には迅速な検索を可能にする順序付けられたリストを格納するためのBSTに移行します。