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

【C++】連結リストからxより大きいノードをすべて削除する方法

このチュートリアルでは、単方向連結リスト(Singly Linked List)から、指定した値 x より大きいデータを持つノードをすべて削除する方法 を解説します。

まずは、問題を解くための手順を確認しましょう。

解決の手順

  1. データ(data)と次ノードへのポインタ(next)を持つ構造体を定義します。

  2. 連結リストにノードを挿入する関数を作成します。

  3. ダミーデータを使って連結リストを初期化します。

  4. 連結リストを先頭から順に走査し、現在のノードのデータが x より大きいかどうかを判定します。

  5. x より大きい場合は、そのノードを削除します。

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

ノードを削除する関数では、以下の3つのケースを考慮する必要があります。

  • 先頭ノードの場合: head ポインタを次のノードへ移動させます。

  • 中間ノードの場合: 前のノードの next ポインタを、削除対象ノードの次のノードにつなぎ直します。

  • 末尾ノードの場合: 前のノードの next ポインタを NULL にして、リンクを解除します。

サンプルコード

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

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

実行結果

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

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

この例では x = 3 としているため、4 以上の値を持つノード(4、5、6)が削除され、1 → 2 → 3 の連結リストだけが残ります。

処理のポイント

  • 先頭ノードが条件に該当する場合でも正しく動作するよう、head へのポインタ(二重ポインタ)を使用しています。

  • 内側の while ループで「x 以下のノード」をスキップし、該当ノードが見つかった時点で削除処理を行うことで、リスト全体を一度の走査で処理できます。

  • 計算量は O(n)、必要な追加メモリは O(1) と効率的です。

まとめ

本記事では、C++ を使って単方向連結リストから x より大きい値を持つノードをすべて削除する方法を学びました。先頭・中間・末尾という位置ごとの削除処理の違いを理解することは、連結リスト操作の基礎として非常に重要です。チュートリアルについて質問がある場合は、コメント欄でお気軽にお尋ねください。

  1. C++で二分木の特定ノードから距離Kにあるすべてのノードを出力する方法

    問題の概要本記事では、二分木・ターゲットノード・整数Kが与えられたとき、ターゲットノードから距離Kにあるすべてのノードを出力するアルゴリズムをC++で実装して解説します。二分木(Binary Tree)とは、各ノードが最大2つの子ノード(0個・1個・2個)を持つことができる特殊な木構造です。問題例まず、具体例を使って問題を理解しましょう。下図のような二分木を考えます。K = 2ターゲットノード: 9出力:5 1 3説明:ここでいう「距離」は、ターゲットノードより上の階層・下の階層・同じ階層のいずれのノードに対しても定義されます。そのため、方向を問わず距離Kにあるノードをすべて出力する必要があり

  2. C++で葉ノードから距離kにあるすべてのノードを出力する方法

    問題概要この問題では、二分木と数値Kが与えられ、葉ノードから距離Kにあるすべてのノードを出力することが求められます。二分木(Binary Tree)とは、各ノードが最大2つの子ノード(1つ・2つ・または0個)を持つ特別な木構造のことです。葉ノード(Leaf Node)とは、二分木の末端に位置するノードを指します。この問題における「葉ノードからの距離」とは、葉ノードよりも上位のレベルに位置するノードを意味します。たとえば、レベル4にある葉ノードから距離2のノードは、レベル2に存在することになります。具体例で理解しよう次の図のような二分木を例に考えてみましょう。K = 2 の場合、出力:6 9解法