興味深いアルゴリズム - リンク リスト: 柔軟性と効率の完璧な組み合わせ

1. リンクリストならではの魅力

1.1 概要と定義

Linked List (Linked List) は、一般的な基本的なデータ構造です。データを「リンク」して保存します。これは、メモリ上に点在するデータを保存するのと同じです。データの各部分は、記憶要素とポインタで構成されます。このうち、記憶要素は、はデータの保存または表現に使用され、ポインタは次の記憶要素のアドレスをマークするために使用されます。このようにして、散在するデータがリンクされて完全なデータ保存および表現システムが形成されます。

1.2 リンクリストを使用する理由

配列などの他の線形データ構造と比較して、リンク リストには多くの利点と特徴があります。リンク リストを使用する主な理由は次のとおりです。

  • 柔軟なメモリ割り当て: リンク リストはメモリ内の連続した領域を占有する必要がないため、メモリ使用率の観点から、リンク リストはメモリの使用を分散し、より柔軟にすることができます。また、ノードの追加や削除には大規模なデータ移行が必要ないため、リンクリストの方が挿入や削除の操作が効率的です。

  • 効率的な挿入と削除: 配列では要素の挿入と削除に多数の要素を移動する必要がありますが、リンク リストでは対応するポインターを変更するだけで済むため、挿入と削除の操作が非常に効率的になります。

  • 他のデータ構造に簡単に拡張可能: リンク リストは、スタック、キュー、ハッシュ テーブル、グラフなどの他のデータ構造に簡単に拡張でき、強力な拡張性を示します。

一般に、リンク リストは、その特殊な格納方法により高い柔軟性と効率性を備えています。データ要素の頻繁な挿入と削除が必要なシナリオなど、特定の問題を解決する場合には、明らかに配列よりもリンク リストの方が適しています。したがって、リンク リストを理解して習得することは、コンピューター サイエンスとプログラミングを学ぶ人全員が習得する必要がある基本知識です。

2. リンクされたリストのノードを探索する

2.1 ノードの構成

リンク リストの基本要素はノードです。各ノードは 2 つの基本要素で構成されます。データを格納する領域 (通常、要素またはデータ フィールドと呼ばれます) と、リンク リスト内の他のノードを指す 1 つ以上のリンクです。リンクの数はリンク リストのタイプによって異なります。単一リンク リストの各ノードには次のノードを指すリンクがあり、二重リンク リストの各ノードには前のノードと次のノードをそれぞれ指す 2 つのリンクがあります。循環リンク リストの最後のノードには、リンク リストの最初のノードを指すリンクが 1 つあります。

2.2 ノード間の接続形態

上で述べたように、単一リンク リスト内の各ノードには、次のノードへのリンクが 1 つだけ含まれます。したがって、ノード間の接続は、リンク リストの先頭ノードからリンク リストの末尾ノードまでの一方向です。さらに、リンク リストには通常、リンク リストの開始点として特別なヘッド ノード (head) があり、リンク リストの終了点として末尾ノード (tail) が存在する場合もあります。これらには実際のデータは含まれず、単に再生されるだけです。補助的な役割。

二重リンク リストには 2 つのリンクが含まれており、1 つは前のノードを指し、もう 1 つは次のノードを指します。したがって、二重リンク リスト内のノードは双方向に接続されており、どのノードからでもリンク リスト全体を前方または後方にたどることができます。

循環リンク リストは、最後のノードがリンク リストの最初のノードを指すリンクを持ち、リング構造を形成する特別なリンク リストです。一方向循環リンク リストの場合、このリンクはヘッド ノードを指します。双方向循環リンク リストの場合、ヘッド ノードを指すリンクに加えて、末尾ノードを指すリンクもあります。

2.3 ノードの実装

プログラミングでは、通常、リンク リスト ノードはクラスまたは構造体を使用して実装されます。たとえば、Java では、最も基本的な単一リンク リスト ノードの実装は次のようになります。

public class Node {
    
    
    int data;
    Node next;
}

dataこのクラスは、データを保存し、next次のノードにリンクするために使用されるノードを定義します。ダブル リンク リスト ノードの実装は、これに基づいて前のノードにリンクを追加します。

public class Node {
    
    
    int data;
    Node next;
    Node prev;
}

上記は、リンク リストの基本単位であるリンク リスト ノードの一般的な説明です。リンク リスト ノードは、ポインタまたは参照を介して他のノードに接続され、複雑なリンク リスト構造を形成します。リンクリストの動作メカニズムを理解するには、ノードの構造を理解することが重要です。

三、リンクリストの基本操作

基本的なデータ構造として、リンク リストには、挿入、削除、検索、走査などの基本的な操作がいくつかあります。以下、それぞれの操作について詳しく説明します。

3.1 挿入操作

挿入操作には、リンクリストの先頭にノードを挿入すること、リンクリストの末尾にノードを挿入すること、リンクリストの途中にノードを挿入することが含まれる。具体的な実装コードは以下のとおりです。

public class LinkedList {
    
    
    Node head; 

    class Node {
    
    
        int data;
        Node next;

        Node(int d) {
    
    
            data = d;
            next = null;
        }
    }

    public void push(int new_data) {
    
       // 在链表头部插入节点
        Node new_node = new Node(new_data);
        new_node.next = head;
        head = new_node;
    }

    public void insertAfter(Node prev_node, int new_data) {
    
      // 在给定节点后插入节点
        if (prev_node == null) {
    
    
            System.out.println("The given previous node cannot be null");
            return;
        }

        Node new_node = new Node(new_data);
        new_node.next = prev_node.next;
        prev_node.next = new_node;
    }

    public void append(int new_data) {
    
      // 在链表尾部插入节点
        Node new_node = new Node(new_data);

        if (head == null) {
    
    
            head = new Node(new_data);
            return;
        }

        new_node.next = null;

        Node last = head;
        while (last.next != null) {
    
    
            last = last.next;
        }

        last.next = new_node;
        return;
    }
}

3.2 削除操作

削除操作には、連結リストの先頭ノードの削除、連結リストの末尾ノードの削除、および連結リスト内の特定のノードの削除が含まれる。具体的な実装コードは以下のとおりです。

public void deleteNode(int key) {
    
     // 删除键为key的节点
    Node temp = head, prev = null;

    if (temp != null && temp.data == key) {
    
    
        head = temp.next;
        return;
    }

    while (temp != null && temp.data != key) {
    
    
        prev = temp;
        temp = temp.next;
    }

    if (temp == null) return;

    prev.next = temp.next;
}

3.3 検索操作

find 操作は、リンクされたリスト内の特定の要素を検索するために使用されます。具体的な実装コードは以下のとおりです。

public boolean search(Node head, int x) {
    
      // 在链表中查找键为x的节点
    Node current = head;
    while (current != null) {
    
    
        if (current.data == x) {
    
    
            return true;
        }
        current = current.next;
    }
    return false;
}

3.4 トラバース操作

トラバーサル操作は、リンクされたリスト内の各要素にアクセスするために使用されます。具体的な実装コードは以下のとおりです。

public void printList() {
    
      // 打印链表的所有节点
    Node tnode = head;
    while (tnode != null) {
    
    
        System.out.print(tnode.data+" ");
        tnode = tnode.next;
    }
}

上記はリンク リストの基本的な操作の一部であり、これらの操作により、リンク リストの読み取り、書き込み、変更などの操作が可能になります。存在

実際の使用では、リンク リストの操作は並べ替え、反転などを含めてさらに複雑になる場合がありますが、基本的にはこれらの基本操作の組み合わせに起因すると考えられます。

4. リンク リストの世界: 一方向のリンク リストだけではない

リンク リストは、データの保存と整理に使用される一般的なデータ構造です。一般的な一方向リンク リストに加えて、二重リンク リスト、循環リンク リスト、スキップ リンク リスト、XOR リンク リストなどの他のタイプのリンク リストがあります。
4. リンク リストの世界: 一方向のリンク リストだけではない

リンク リストの世界は豊かで多彩であり、さまざまな問題の解決に適した独自の利点があります。これらの形式のいくつかを見てみましょう。

4.1 二重リンクリスト

名前が示すように、二重リンク リストは、各ノードに 2 つのリンクがあり、1 つは前のノードを指し、もう 1 つは次のノードを指すことを意味します。二重リンクリストの重要な特性は、両方向に走査できることです。これにより、あるノードから前のノードへの移動や、ノード間に新しいノードを挿入するなど、特定の操作を簡単に実行できるようになります。ノードを挿入または削除すると、最初からたどることなく、前のノードを直接見つけることができます。これは二重リンクリストの大きな利点であり、操作が簡単で効率が高いです。具体的には、二重リンク リストは、両端でのノードの削除と挿入を O(1) の時間計算量でサポートできます。

二重リンクリストノードのJavaコードは次のように表されます。

class Node {
    
    
    int data;       // 节点数据
    Node next;      // 指向下一个节点的指针
    Node prev;      // 指向前一个节点的指针

    Node(int d) {
    
    
        data = d;
        next = null;
        prev = null;
    }
}

4.2 循環リンクリスト

循環リンク リストは、最後の要素がリンク リストの最初の要素を指す、ユニークな形式のリンク リストです。この特性により、チェーンテールからチェーンヘッドへの移行が非常に速くなります。循環リンク リストは、単一循環リンク リストまたは二重循環リンク リストにすることができます。このリンク リスト構造は、循環キューやジョセフ問題などの循環構造の問題を扱うのに特に適しています。
以下は、Java での循環リンク リストの表現です。

Copy code
class Node {
    
    
    int data;        // 节点数据
    Node next;       // 指向下一个节点的指针

    Node(int d) {
    
    
        data = d;
        next = this; // 在创建节点时,将next指向自身,形成一个单节点的循环链表
    }
}

4.3 その他のリンクリスト形式

前述の一般的なリンク リスト形式に加えて、スキップ リスト、XOR リンク リストなどの他の形式のリンク リストがあり、それぞれに特別なアプリケーション シナリオと最適化目標があります。たとえば、ジャンプ リンク リストは主に検索パフォーマンスを最適化し、マルチレベル インデックスを確立することで高速検索を実現するために使用されます。XOR リンク リストは、メモリに制約のある環境でのストレージ容量要件を最適化するリンク リスト形式です。

リンクされたリストの世界は豊かで多彩であることがわかります。連結リストにはさまざまな形式があり、それぞれに特徴がありますが、その基本的な操作や考え方はすべて連結リストの基本概念に基づいています。これらの基本的な概念を習得すると、さまざまな形式のリンク リストを柔軟に使用して、実際的な問題をより適切に解決できるようになります。

V. まとめ

リンク リスト、この一見単純なデータ構造には、非常に豊富なコンテンツが含まれています。これは、一方向の前進パスのように単純なものもあれば、双方向のパスのように複雑なものもあり、さらには閉ループの軌道であることもあります。リンク リストの魅力は、その柔軟なデータ保存方法にあり、非常に低コストでデータ シーケンスの挿入および削除操作を実行でき、データ量が不明な場合や頻繁な操作が必要なシナリオに特に適しています。

リンク リストを学習する過程で、二重リンク リスト、循環リンク リスト、より高度なジャンプ リストなど、リンク リストの特殊な形式についても学びました。日常の開発では、これらのデータ構造を直接実装することはありませんが、それらを理解することは、言語の組み込みデータ構造とクラス ライブラリをより深く理解して使用するのに役立ちます。

もちろん、リンク リストはデータ構造の氷山の一角にすぎません。データ構造の世界には、ツリー、グラフ、ヒープ、ハッシュ テーブルなど、さらに複雑で強力なデータ構造が探索を待っています。それぞれのデータ構造には特有の応用シナリオがあり、それを学びマスターすることで、プログラミングの道をさらに進めることができます。次回のブログでは、引き続きデータ構造の世界を詳しく紹介していきますので、お楽しみに!

「無限に探索し​​、無限に学びましょう」として、私たちは興味深いアルゴリズムの旅を前進し続け、すべてのステップが新しいインスピレーションと楽しみをもたらすことを願っています。

おすすめ

転載: blog.csdn.net/weixin_46703995/article/details/131317967