このセクションでは、一般的でよく使用されるデータ構造であるテーブルについて説明します。 テーブルとは何かを簡単に説明すると、順序よく並べられた要素の集合がテーブルであると言えます。 表の概要 抽象データ型は、いくつかのオブジェクトと一連の操作の組み合わせです。 1. 定義: 線形リストは線形構造であり、n ≥ 0 個のノードの有限シーケンスです。各ノードには、先行ノードはないが後続ノードが 1 つある開始ノードが 1 つだけあり、後続ノードはないが先行ノードが 1 つある終端ノードが 1 つだけあり、その他のすべてのノードには先行ノードと後続ノードが 1 つずつあります。 2. 特性/性質
上の図では、a1 は a2 の前身、ai+1 は ai の後身、a1 には前身がなく、an には後身がなく、n は線形テーブルの長さです。n==0 の場合、線形テーブルは空です。下の図は標準的な線形テーブルです。 リニア テーブルは次のカテゴリに分類されます。 順次格納線形テーブル 順次格納される線形テーブルでは、格納場所が連続しており、各要素のアドレスを簡単に計算できます。 各要素が C 個のストレージ ユニットを占有する場合、Loc(An) = Loc(An-1) + C となり、Loc(An) = Loc(A1)+(i-1)*C となります。 利点:高速クエリ デメリット:挿入と削除の効率が遅い 次の図は、遅い挿入と削除の特徴を鮮明に示しています。 テーブルのシンプルな配列実装 典型的な線形順次ストレージ方法は配列です。テーブル上のすべての操作は、配列を使用して実装できます。配列は固定サイズで作成されますが、必要に応じて容量の 2 倍の別の配列を作成することもできます。以下は拡張の疑似コードです。
配列の実装により、printList は線形時間で実行できますが、findKth (特定の位置にある要素を返す) には一定の時間がかかります。 最悪のケースでは、位置 0 に要素を挿入するには、配列内のすべての要素を 1 つ後ろへ移動する必要があり、要素を削除するには、すべての要素を 1 つ前へ移動する必要があります。どちらの場合も複雑さは O(n) です。平均すると、両方の操作は配列の要素の半分を移動する必要があるため、線形時間がかかりますが、挿入と削除の両方が配列の末尾で発生する場合、挿入と削除の両方にかかる時間は O(1) だけです。 テーブルの先頭で頻繁に挿入や削除が行われる場合は、リンク リストの方が適しています。 チェーン収納リニアテーブル 線形リストのチェーン ストレージ構造の特徴は、任意のストレージ ユニットのセットを使用して線形リストのデータ要素を格納することです。このストレージ ユニットのセットは連続または不連続にすることができます。 利点:配列と比較して、削除と挿入が効率的です デメリット:配列と比較するとクエリ効率が低い 挿入操作を実行するには、次のコードだけが必要です。
削除操作を実行するには、次のコードのみが必要です。
循環リンク リストは、単一リンク リストの終端ノードのポインターの端をヌル ポインターから先頭ノードに変更し、単一リンク リスト全体がループを形成するようにします。このような先頭から末尾まで接続された単一リンク リストは、単一循環リンク リスト、または略して循環リンク リストと呼ばれます。 二重循環リンクリスト 双方向循環リンク リストは、各ノードにその前のノードを指すポインター フィールドがある単方向循環リンク リストです。 空の二重循環リンクリストの場合 二重リンクリストへの挿入 Java コレクション API のテーブル 1. IteratorIterator インターフェースの考え方は、Iterator メソッドを通じて、各コレクションが Iterator インターフェースを実装するオブジェクトを作成してクライアントに返し、オブジェクト内に現在の位置の概念を保存します。
Iterator のメソッドは制限されているため、Collection を走査する以外の操作に Iterator を使用することは困難です。 Iterator には remove() メソッドも含まれています。このメソッドの目的は、next()*** によって返された項目を削除することです (next() を再度呼び出すまで、remove() を再度呼び出すことはできません)。 反復処理されるコレクションの構造が変更された場合 (つまり、コレクションに対して追加、削除、またはクリアが使用された場合)、反復子は有効ではなくなります (その後反復子を使用すると ConcurrentModificationException がスローされます)。反復子が次の項目として項目を提供する準備をし、その後その項目が削除されるのを避けるために、反復子はすぐに必要なときにのみ取得する必要があります。ただし、イテレータが独自の削除メソッドを呼び出す場合、イテレータは引き続き有効です。 2. リストインターフェース
List ATD の一般的な実装には、ArrayList と LinkedList の 2 つがあります。 ArrayList の利点は、get および set 呼び出しに一定の時間がかかることです。欠点は、ArrayList の末尾が変更されない限り、新しい項目の挿入と既存の項目の削除にコストがかかることです。 LinkedList の利点は、テーブルの先頭での追加と削除に一定の時間がかかることです。欠点は、インデックス付けが容易ではなく、テーブルの末尾に近くない限り、get 呼び出しにコストがかかることです。
引数として ArrayList または LinkedList が渡されるかどうかに関係なく、add の各呼び出しはリストの末尾で行われるため、一定の時間がかかるため、makeList1 の実行時間は O(N) になります (ArrayList の偶発的な拡張は無視します)。一方、リストの先頭にいくつかの項目を追加してリストを作成すると、次のようになります。
LinkedList の場合、実行時間は O(N) ですが、ArrayList の場合、先頭への追加は O(N) 操作であるため、実行時間は O(n^2) です。
ここで、ArrayList の実行時間は O(N) ですが、LinkedList の場合、get の呼び出しは O(N) 操作であるため、実行時間は O(n^2) になります。ただし、拡張 for ループを使用すると、反復子が 1 つの項目から次の項目に効率的に進むため、どのリストに対しても O(N) 時間で実行されます。 ArrayList と LinkedList はどちらも、コレクションの contains メソッドと remove メソッドの呼び出しに線形時間がかかることから、検索には非効率的です。 例: LinkedList クラスで remove メソッドを使用する例 1: 6、5、1、4、2 の 5 つの数字があり、メソッドを呼び出した後にすべての偶数を削除する必要があるとします。 アイデア:
ArrayList と LinkedList はどちらも削除には非効率的です。LinkedList では、位置 i に到達するのにコストがかかります。
LinkedListの場合、上記のソリューションの実行時間はO(n^2)です。イテレータを使用するとより効率的になります。もちろん、イテレータを使用する場合、Listの 削除しないと、次の例のように例外がスローされます (拡張 for ループでは、下部でイテレータが引き続き使用されます)。
上記の問題を解決するには、イテレータの remove メソッドを直接使用できます。これは合法です。
Iterator を使用した後、Iterator は削除する必要のあるノードに既に配置されているため、LinkedList の削除操作には O(n) の時間がかかります。 Iterator を使用しても、ArrayList の削除メソッドは、配列要素を削除するときに移動する必要があるため、依然として O(n^2) です。 ListIterator インターフェース ListIterator インターフェースは Iterator、hasNext、hasPrevious メソッドを拡張し、先頭からも末尾からも走査できるようにします。add は現在の位置に新しい項目を挿入し、set メソッドは hasNext または hasPrevious を呼び出して Iterator によって返された現在の値を変更します。
ArrayList の実装 次に、ArrayList を独自に記述し、ジェネリックをサポートします。コードは次のとおりです。
ここで言及しておくべきことは、新しいT[]を直接作成することはできないが、次のコードを通じて汎用配列を作成する必要があるということである。
もう一つ言及する価値のある点は、ArrayIteratorでMyArrayList.this.removeを使用するのは、イテレータ自身の削除との競合を避けるためである。
LinkedList の実装 LinkedList では、最前面のノードはヘッド ノードと呼ばれ、最背面のノードはテール ノードと呼ばれます。これら 2 つの追加ノードの存在により、多くの特殊なケースが排除され、コーディングが大幅に簡素化されます。たとえば、ヘッド ノードが使用されていない場合、最初のノードを削除するのは特別なケースです。これは、削除中にリンク リストを最初のノードのチェーンに再調整する必要があり、削除アルゴリズムでは通常、削除されたノードの前のノードを参照する必要があるためです (ヘッド ノードがない場合、最初のノードの前にノードがない特別なケースになります)。
1. modCount は、リンク リストの作成以降に行われた変更の数を表します。追加または削除の各呼び出しにより、modCount が更新されます。アイデアとしては、イテレータが作成されると、コレクションの modCount が格納されます。イテレータ メソッド (next または remove) の各呼び出しでは、リンク リスト内の現在の modCount をイテレータに格納されている modCount と比較し、2 つのカウントが一致しない場合は ConcurrentModificationException をスローします。 2. LinkedListIterator では、currentNode は next の呼び出しによって返される項目を含むノードを表します。 currentNode が endNote に配置されている場合、next の呼び出しは無効であることに注意してください。 LinkedListIterator の削除メソッドでは、ArrayIterator とは異なり、currentNode ノードは前のノードの削除の影響を受けないため、currentNode は変更されません (ArrayIterator では、項目が移動され、current を更新する必要があります)。 |
【環球時報記者 徐陸明】6月17日、「国防ニュース」ウェブサイトの報道によると、最新の軍事予算文書...
[51CTO.com クイック翻訳] Zstandard (Zstd とも呼ばれる) は、Faceb...
[51CTO.com からのオリジナル記事] 2016年、国内投資家のVRへの熱意はまだ薄れていなか...
生成型 AI の新たな波に直面して、私たちはそれに積極的に適応するか、AI (または AI を受け入...
[[284994]]データシャーディングまずは例を見てみましょう。多くの場合、キャッシュには Re...
この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI)より許可を得て転載...
人工知能 (AI) とディープラーニングはあらゆるところに存在し、今や都市の景観を一変させる可能性を...
ビッグデータダイジェスト制作著者: カレブ西暦79年、ベスビオ山が噴火し、その麓にあったポンペイの街...
[[428679]] Tesla、Google、Microsoft、Facebook などのテクノ...
C言語を学んだ友人やIT関係の人ならアルゴリズムには詳しいと思います。したがって、分野が異なれば、ア...
産業用ロボットは、さまざまな産業用タスクを自動的に実行できる一種の機器として、製造、組み立て、梱包、...
グリーンロボットは気候変動と闘い、より良い未来へと導くのに役立ちます。私たちは通常、ロボットが「環境...
大規模言語モデル (LLM) は今年非常に人気がありました。しかし、その驚異的な効果の背後には、巨大...
2020年は人工知能(AI)にとって節目の年です。今年、新型コロナウイルス感染症のパンデミックが世界...