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

C++で双方向リンクリストから指定した値より小さいノードをすべて削除する方法

このチュートリアルでは、C++を使って双方向リンクリスト(Doubly Linked List)から、指定した値よりも小さいデータを持つノードをすべて削除する方法を解説します。

問題を解くための手順

以下の手順に従ってプログラムを実装していきます。

  • data(データ)、prev(前のノードへのポインタ)、next(次のノードへのポインタ)を持つ構造体を定義します。
  • 双方向リンクリストにノードを挿入する関数を作成します。
  • サンプルデータを使って双方向リンクリストを初期化します。
  • リンクリストを先頭から順に走査し、現在のノードのデータが指定した値より小さいかどうかを判定します。
  • 現在のデータが指定値より小さい場合は、そのノードを削除します。
  • ノードを削除する関数を実装します。削除時には以下の3つのケースを考慮する必要があります。
    • 先頭ノードの場合:headポインタを次のノードに移動します。
    • 中間ノードの場合:次のノードを前のノードにリンクし直します。
    • 末尾ノードの場合:前のノードのnextリンクを解除します。

実装例

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

#include <bits/stdc++.h>
using namespace std;
struct Node {
   int data;
   Node *prev, *next;
};
void insertNode(Node** head_ref, int new_data) {
   Node* new_node = (Node*)malloc(sizeof(struct Node));
   new_node->data = new_data;
   new_node->prev = NULL;
   new_node->next = (*head_ref);
   if ((*head_ref) != NULL) {
      (*head_ref)->prev = new_node;
   }
   (*head_ref) = new_node;
}
void deleteNode(Node** head_ref, Node* del) {
   if (*head_ref == NULL || del == NULL) {
      return;
   }
   if (*head_ref == del) {
      *head_ref = del->next;
   }
   if (del->next != NULL) {
      del->next->prev = del->prev;
   }
   if (del->prev != NULL) {
      del->prev->next = del->next;
   }
   free(del);
   return;
}
void deleteSmallerNodes(Node** head_ref, int K) {
   Node* temp = *head_ref;
   Node* next;
   while (temp != NULL) {
      next = temp->next;
      if (temp->data < K) {
         deleteNode(head_ref, temp);
      }
      temp = next;
   }
}
void printLinkedList(Node* head) {
   while (head != NULL) {
      cout << head->data << " -> ";
      head = head->next;
   }
}
int main() {
   Node* head = NULL;
   insertNode(&head, 1);
   insertNode(&head, 2);
   insertNode(&head, 3);
   insertNode(&head, 4);
   insertNode(&head, 10);
   insertNode(&head, 11);
   insertNode(&head, 12);
   int K = 10;
   cout << "Linked List before deletion:" << endl;
   printLinkedList(head);
   deleteSmallerNodes(&head, K);
   cout << "\nLinked List after deletion:" << endl;
   printLinkedList(head);
}

出力結果

上記のプログラムを実行すると、以下の結果が得られます。

Linked List before deletion:
12 -> 11 -> 10 -> 4 -> 3 -> 2 -> 1 ->
Linked List after deletion:
12 -> 11 -> 10 ->

コードのポイント

deleteSmallerNodes関数では、走査中にノードを削除しても処理を続行できるよう、ループの先頭で次のノードへのポインタをあらかじめ保存しています。これにより、ノードが解放された後も安全にリンクリストを走査できます。

また、deleteNode関数では、先頭ノード・中間ノード・末尾ノードの3つのケースを統一的に処理しています。prevとnextの双方のポインタを適切につなぎ直すことで、双方向リンクリストの整合性が保たれます。

まとめ

本チュートリアルでは、双方向リンクリストから指定した値より小さいノードをすべて削除する方法を学びました。ノード削除時には、先頭・中間・末尾の3つのケースを適切に処理することが重要です。本チュートリアルについてご不明な点があれば、コメント欄でお気軽にお尋ねください。

  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解法