C++で単一連結リスト(片方向リンクリスト)から特定の要素を検索する方法
単一連結リスト(片方向リンクリスト)が与えられたとき、その中から特定の要素を検索するのが本記事のテーマです。要素が見つかった場合は「Present」、見つからなかった場合は「Not Present」を出力します。
入力例1
1→ 2→ 3→ 4→ 5→ 6
「7」を検索する場合
出力
Not Present
解説: 与えられた単一連結リストの中に「7」は存在しないため、「Not Present」を返します。
入力例2
1→ 2→ 3→ 4→ 5
「2」を検索する場合
出力
Present
解説: 与えられた単一連結リストの中に「2」が存在するため、「Present」を返します。
この問題を解くアプローチ
単一連結リスト内の特定の要素を検索するには、大きく分けて2つのアプローチがあります。ひとつは再帰的に要素の存在を確認する方法、もうひとつはループを使って反復的に確認する方法です。
再帰的なアプローチでは、リンクリストが空であればfalseを返し、現在のノードのデータ値が検索対象の要素と一致すればtrueを返します。反復的なアプローチでは、先頭ポインタから順に各ノードの値と比較していき、一致するかどうかに応じてtrueまたはfalseを返します。
入力を受け取り、ノードを挿入して単一連結リストを初期化します。
ブール型の再帰関数
searchRecursive(node* head, int element)は、リンクリストの先頭ポインタと検索対象のキー要素を引数として受け取ります。まず、先頭ポインタがNULL(リンクリストが空)である場合はfalseを返します。
検索対象の要素が現在の先頭ノードのデータと一致する場合はtrueを返します。
一致しない場合は、次のノードを渡して同じ関数を再帰的に呼び出します。
なお、このアルゴリズムの時間計算量はO(n)、空間計算量はO(1)です(再帰呼び出しによるスタック消費を考慮するとO(n))。リンクリストの長さに比例して処理時間が増加することに注意してください。
コード例
#include<iostream>
using namespace std;
class node{
public:
int data;
node* next;
node(int d){
data = d;
next = NULL;
}
};
void insertAt(node*& head, int data){
node* n = new node(data);
n->next = head;
head = n;
}
bool searchRecursive(node* head, int key){
if(head == NULL){
return false;
}
if(head->data == key){
return true;
}
else{
return searchRecursive(head->next, key);
}
}
void printNode(node* head){
while(head != NULL){
cout << head->data << "->";
head = head->next;
}
cout << endl;
}
int main(){
node* head = NULL;
insertAt(head, 5);
insertAt(head, 4);
insertAt(head, 3);
insertAt(head, 2);
insertAt(head, 1);
printNode(head);
if(searchRecursive(head, 7)){
cout << "Present" << endl;
}
else{
cout << "Not Present" << endl;
}
}
出力
上記のコードを実行すると、以下のような結果が出力されます。
1->2->3->4->5-> Not Present
与えられたリンクリスト 1→2→3→4→5 の中に要素「7」は存在しないため、「Not Present」が返されます。もし検索対象を「3」などリスト内に存在する値に変更すれば、「Present」と出力されることを確認できます。
-
C++で連結リストの交互ノードの合計を求める方法(反復法・再帰法)
問題概要 この記事では、連結リスト(リンクリスト)が与えられたときに、その交互ノード(0、2、4…番目のノード)の値の合計を求める方法を解説します。 連結リストとは、リンク(ポインタ)によって順次接続されたデータ構造の列です。各ノードはデータ本体と、次のノードを指す参照を持っています。 今回の課題は、連結リストのうち位置 0、2、4、6 … にあるノード、つまり先頭から1つおきのノードの値をすべて加算することです。 入出力例 入力: 4 → 12 → 10 → 76 → 9 → 26 → 1 出力: 24 説明: 交互ノードを取り出すと − 4 + 10 + 9 + 1 = 24 解決の考
-
【C++】再帰を使ってリンクリストの交互ノードを出力する方法
リンクリスト(連結リスト)とはリンクリストは、各要素(ノード)をメモリ上の連続しない領域に格納できる線形データ構造です。各ノードにはデータ本体と、次のノードを指すポインタが含まれており、ポインタをつなぐことで一連のリストとして扱うことができます。問題の概要今回は、与えられたリンクリストを走査し、交互(ひとつおき)のノードだけを出力するプログラムを作成します。具体的には、1番目・3番目・5番目…というように、奇数番目の要素のみを順に出力していきます。入出力例入力 : 2 -> 4 -> 1 -> 67 -> 48 -> 90 出力 : 2 -> 1 ->