C++で単一連結リストから末尾ノード(テールノード)を削除する方法
連結リスト(リンクリスト)とは、線形データ構造の一種であり、複数の「ノード」で構成されます。各ノードには2つのフィールドがあり、1つは格納する値(データ)、もう1つは次のノードのアドレスを保持するためのポインタです。
本記事の課題は、連結リストの末尾からノードを削除することです。連結リストの最後にあるノードは「テールノード(末尾ノード)」と呼ばれます。なお、連結リストが空の場合はNULLを返します。
入出力例
入力1: 1 → 2 → 3 → 4 → 5
出力: 1 → 2 → 3 → 4 →
説明: 与えられた単一連結リストの末尾にあるノードは「5」です。最後のノードを削除すると、出力は 1 → 2 → 3 → 4 → となります。
入力2: 5 → 8 → 3
出力: 5 → 8 →
説明: 与えられた単一連結リストの末尾にあるノードは「3」です。末尾のノードを削除すると、出力は 5 → 8 → となります。
問題の解決アプローチ
この問題を解くシンプルな方法は、「前のノード(previous)」を表すポインタを用意し、現在のポインタ(current)が連結リストの最後のノードを指した時点で、その直前のノード情報を保持しておくというものです。
具体的には、連結リストの全ノードを順に走査し、現在のノードが末尾ノードに到達したかどうかを確認しながら進めます。そして最後に、末尾ノードを削除した連結リストを返します。
アルゴリズムの手順
- ノードを挿入して連結リストを初期化します。
- 関数
insertAtFirst(node*&head, int data)により、すべてのノードを連結リストの先頭に挿入します。 - 関数
deleteAtTail(node*head)は、先頭(head)を指すポインタを受け取ります。 - previous ノード用のポインタを作成し、NULLで初期化します。
- head を指す一時的なノードポインタ(temp)を作成します。
- temp ポインタが連結リストの末尾に到達するまで走査を続けます。
- 走査中、各ステップで temp の値を previous ポインタに保存します。
- 末尾に到達したら、temp ポインタが指すノードを削除(delete)します。
- previous ノードの next を NULL に設定して完了です。
C++実装例
#include<iostream>
using namespace std;
class node{
public:
int data;
node*next;
node(int d){
data=d;
node*next= NULL;
}
};
void insertAtFirst(node*&head, int data){
node*n= new node(data);
n->next= head;
head=n;
}
void printNode(node*head){
while(head!=NULL){
cout<<head->data<<"->";
head=head->next;
}
cout<<endl;
}
void deleteatTail(node*head){
node*prev= NULL;
node*temp= head;
while(temp->next!=NULL){
prev= temp;
temp=temp->next;
}
delete temp;
prev->next= NULL;
return;
}
int main(){
node*head= NULL;
insertAtFirst(head,5);
insertAtFirst(head,4);
insertAtFirst(head,3);
insertAtFirst(head,2);
insertAtFirst(head,1);
deleteatTail(head);
printNode(head);
}実行結果
上記のコードを実行すると、以下の出力が得られます。
1→2→3→4→
コードの解説
入力として与えられた単一連結リストは 1 → 2 → 3 → 4 → 5 であり、この連結リストの末尾ノードは「5」です。deleteatTail 関数では、temp ポインタが next == NULL となる(=末尾である)までループを回し、その間 previous ポインタに直前のノードを記録していきます。末尾ノードを delete で解放した後、previous ノードの next を NULL に設定することで、新しい末尾として正しく連結リストが更新されます。その結果、削除後の連結リストは 1 → 2 → 3 → 4 → となります。
-
C++で双方向リンクリストの指定位置にあるノードを削除する方法
このチュートリアルでは、C++を使って双方向リンクリスト(doubly linked list)から、指定された位置にあるノードを削除する方法を解説します。問題を解くための手順まずは、全体の流れを確認しましょう。データ本体と prev(前)・next(次)の2つのポインタを持つ構造体を定義します。双方向リンクリストにノードを挿入する関数を作成します。ダミーデータを使ってリンクリストを初期化します。削除対象となるノードの位置(position)を設定します。リンクリストを先頭から走査し、指定位置に該当するノードを見つけます。ノードを削除する関数を実装します。削除時には、以下の3つのケースを考慮す
-
C++で循環単方向リンクリストを実装する方法【サンプルコード付き】
循環単方向リンクリスト(Circular Singly Linked List)は、自己参照構造体を用いて作成されたノードから構成されるデータ構造の一種です。各ノードは「データ」と「次のノードへの参照(ポインタ)」という2つの部分で構成されています。リンクリスト全体へアクセスするには、先頭ノードへの参照だけがあれば十分です。この先頭ノードは「ヘッド(head)」と呼ばれます。そして、リストの最後のノードは先頭ノード(ヘッド)を指します。このようにリストが輪のように閉じていることから、「循環リンクリスト」と呼ばれています。以下に、循環単方向リンクリストを実装するC++プログラムの例を示します。サ