【C言語】連結リストを実際には反転せずに逆順で表示する方法
この課題では、再帰関数を使用して、与えられた連結リスト(リンクリスト)を逆順に表示します。ポイントは、リストそのものを反転させるのではなく「逆順に表示する」だけである点です。つまり、ノードのつながりの順序は元のまま一切変わりません。
仕組みとしては、先頭ノードのアドレスを持つヘッドポインタが、リストの末尾ノードに格納されている NULL が見つかるまで次々と次のノードへ移動し、その後、呼び出しが戻りながら各ノードのデータを表示していきます。
実行例
Input: 29 34 43 56 Output: 56 43 34 29
まず、ノードをリストに挿入し、ポインタを挿入済みのノードに向けます。リストが完成したら、テンポラリ(temp)ポインタを先頭ノードで初期化し、末尾ノードは何も指していないため、ノードの next アドレスが NULL になるまで順に進めていきます。その後、末尾ノードからヘッドポインタに向かってリストを逆にたどることで、リストを実際に反転させることなく、逆順の内容を表示できます。
アルゴリズム
START
Step 1 -> 構造体型のノード変数を作成する
int 型の data を宣言
ノード型のポインタ *next を宣言
Step 2 -> 関数 void reverse(node* head) を宣言
IF head == NULL ならば
return
reverse(head->next) を呼び出す
head->data を表示する
Step 3 -> 関数 void push(node** header, char newdata) を宣言
malloc を使用してメモリを確保する
newnode->data = newdata を設定
newnode->next = (*header) を設定
(*header) = newnode を設定
Step 4 -> main() 内で
node* head = NULL としてリストを作成
push(&head, 56) で要素を挿入
reverse(head) を呼び出す
STOP
C言語での実装例
以下のコードは、上記アルゴリズムのC言語による実装です。
#include<stdio.h>
#include<stdlib.h>
// ノード用の構造体を作成
struct node {
int data;
node* next;
};
// リスト内のデータを逆順に表示する関数
void reverse(node* head) {
if (head == NULL)
return;
reverse(head->next);
printf("%d ", head->data);
}
// ノードをリストに追加する関数
void push(node** header, char newdata) {
struct node* newnode = (struct node*)malloc(sizeof(struct node));
newnode->data = newdata;
newnode->next = (*header);
(*header) = newnode;
}
int main() {
node* head = NULL;
push(&head, 56); // 56 をリストに追加
push(&head, 43);
push(&head, 34);
push(&head, 29);
reverse(head);
return 0;
}
解説:なぜ再帰で逆順表示できるのか?
再帰呼び出しでは、関数が自分自身を呼び出した時点ではまだ printf が実行されていません。まず再帰の最深部(NULL の判定)まで到達し、そこから呼び出しが戻る過程で各ノードのデータが順に表示されます。これは「後入れ先出し(LIFO)」のスタック構造を利用した手法であり、ポインタをつなぎ替えることなく、末尾から先頭へとデータを出力できます。計算量は O(n)、再帰に必要なスタック領域も O(n) となります。
出力結果
上記のプログラムを実行すると、以下の出力が得られます。
reverse of a linked list 56 43 34 29
-
C言語で連結リストの交互ノードを出力する方法(反復法)
この問題では、与えられた連結リストから交互のノードを出力するプログラムを作成します。つまり、1つ飛ばしでノードを表示していく処理を、反復法(イテレーティブな手法)を用いて実装します。 反復法とは、条件が真(true)である限り繰り返し実行されるループを使用する手法のことです。 例えば、リストに 29、34、43、56、88 というノードが格納されている場合、出力結果は交互ノードである 29、43、88 となります。 例 入力: 29->34->43->56->88 出力: 29 43 88 アプローチ 基本的な考え方は、リストを最後のノードまで走査するというものです。走
-
Cプログラムで追加領域やリストの変更なしに連結リストを逆順に表示する方法
この課題は、連結リスト(リンクリスト)のノードを末尾から先頭に向かって表示するというものです。ただし、追加のメモリ領域を使用しないことが条件です。つまり、再帰呼び出しやスタックのような補助変数・データ構造を使わず、先頭ノードを指すヘッドポインタだけを利用して実現する必要があります。例入力:10 21 33 42 89 出力:89 42 33 21 10連結リストを逆順に表示する方法はいくつか考えられます。例えば、以下のようなアプローチが挙げられます。再帰的な手法:関数呼び出しのスタックを使用するため、O(n) の追加領域が必要になります。リスト自体を反転させる手法:元の連結リストに変更を加えて