C++
 Computer >> コンピューター >  >> プログラミング >> C++

【C++入門】連結リストから交互のノードを削除する方法

このチュートリアルでは、C++を使って単方向連結リスト(Singly Linked List)から交互のノードを削除する方法を解説します。

解決までの手順

全体の流れは以下の通りです。

  • データ(data)と次ノードへのポインタ(next)を持つ構造体を定義する
  • 単方向連結リストにノードを挿入する関数を作成する
  • ダミーデータで連結リストを初期化する
  • 連結リストを先頭から順に走査する
  • 直前のノード(prev)を保持しながら、交互のノードを削除していく

ノード削除時に考慮すべき3つのケース

ノードを削除する処理では、対象ノードの位置に応じて次の3つのケースを考慮する必要があります。

  • 先頭ノードの場合:headポインタを次のノードへ移動させる
  • 中間ノードの場合:次のノードを直前のノードに連結する
  • 末尾ノードの場合:直前のノードからのリンクを解除する

それでは、実際のコードを見ていきましょう。

サンプルコード

#include <bits/stdc++.h>
using namespace std;
struct Node {
    int data;
    Node *next;
};
void deleteAlternateNodes(Node *head) {
    if (head == NULL)
        return;
    Node *prev = head;
    Node *node = head->next;
    while (prev != NULL && node != NULL) {
        prev->next = node->next;
        free(node);
        prev = prev->next;
        if (prev != NULL) {
            node = prev->next;
        }
    }
}
void insertNode(Node** head_ref, int new_data) {
    Node* new_node = new Node();
    new_node->data = new_data;
    new_node->next = (*head_ref);
    (*head_ref) = new_node;
}
void printLinkedList(Node *node) {
    while (node != NULL) {
        cout << node->data << " -> ";
        node = node->next;
    }
}
int main() {
    Node* head = NULL;
    insertNode(&head, 1);
    insertNode(&head, 2);
    insertNode(&head, 3);
    insertNode(&head, 4);
    insertNode(&head, 5);
    insertNode(&head, 6);
    cout << "Linked List before deletion:" << endl;
    printLinkedList(head);
    deleteAlternateNodes(head);
    cout << "\nLinked List after deletion:" << endl;
    printLinkedList(head);
    return 0;
}

実行結果

上記のプログラムを実行すると、次のような出力が得られます。

Linked List before deletion:
6 -> 5 -> 4 -> 3 -> 2 -> 1 ->
Linked List after deletion:
6 -> 4 -> 2 ->

アルゴリズムのポイント

この実装では、ポインタ prev が残しておきたいノードを指し、その直後のノード node を削除対象として扱います。prev->next = node->next によって削除対象ノードをリストから切り離し、free() でメモリを解放した後、prev を次の残存ノードへ進めて同様の処理を繰り返します。

リストの長さを n とすると、時間計算量は O(n)、追加で必要なメモリは O(1) と非常に効率的です。

まとめ

今回は、単方向連結リストから交互のノードを削除する方法を学びました。ポインタ操作の理解を深めるのに最適な題材なので、ぜひご自身でもコードを書いて試してみてください。チュートリアルの内容について質問や不明な点がある場合は、コメント欄でお気軽にお知らせください。

  1. C++で循環リンクリストのノード数をカウントする方法

    ノードから構成される循環リンクリスト(Circular Linked List)が与えられ、そのリスト内に存在するノードの総数を求めるのが課題です。 循環リンクリストとは、連結リストの一種であり、最初の要素が最後の要素を指し、最後の要素が最初の要素を指すという特徴を持つデータ構造です。片方向リンクリスト(Singly Linked List)でも双方向リンクリスト(Doubly Linked List)でも、この循環リンクリストとして実装することが可能です。 以下のプログラムでは、片方向リンクリストを循環リンクリストとして実装し、その中に含まれるノード数をカウントする方法を紹介します。 具体

  2. 【C++】再帰を使ってリンクリストの交互ノードを出力する方法

    リンクリスト(連結リスト)とはリンクリストは、各要素(ノード)をメモリ上の連続しない領域に格納できる線形データ構造です。各ノードにはデータ本体と、次のノードを指すポインタが含まれており、ポインタをつなぐことで一連のリストとして扱うことができます。問題の概要今回は、与えられたリンクリストを走査し、交互(ひとつおき)のノードだけを出力するプログラムを作成します。具体的には、1番目・3番目・5番目…というように、奇数番目の要素のみを順に出力していきます。入出力例入力 : 2 -> 4 -> 1 -> 67 -> 48 -> 90 出力 : 2 -> 1 ->