C言語で単方向リンクリストを使って数値を逆順に表示する方法
リンクリスト(連結リスト)とは
リンクリストは動的メモリ割り当てを利用するデータ構造で、複数の「ノード」が連なった集合体です。各ノードはデータ部分とリンク部分(次のノードへのポインタ)の2つの要素で構成されています。
リンクリストの種類
C言語で扱われる主なリンクリストには、以下の4種類があります。
- 単方向リンクリスト
- 双方向リンクリスト
- 循環単方向リンクリスト
- 循環双方向リンクリスト
単方向リンクリストの構造
下の図は、単方向リンクリストの構造を示したものです。各ノードがデータと次ノードへのポインタを持ち、末尾ノードのポインタはNULLを指します。

数値を逆順に表示するCプログラム
以下は、単方向リンクリストに入力した数値を逆順に表示するCプログラムです。「ノードの作成(createNodeList)」「リストの反転(reverseDispList)」「リストの表示(displayList)」という3つの関数で構成されています。
#include <stdio.h>
#include <stdlib.h>
struct node {
int num;
struct node *nextptr;
}*stnode;
void createNodeList(int n);
void reverseDispList();
void displayList();
int main(){
int n;
printf("\n\n single Linked List : print it in reverse order :\n");
printf("------------------------------------------------------------------------------\n");
printf(" Input the number of nodes : ");
scanf("%d", &n);
createNodeList(n);
printf("\n Data entered in the list are : \n");
displayList();
reverseDispList();
printf("\n The list in reverse are : \n");
displayList();
return 0;
}
void createNodeList(int n){
struct node *fnNode, *tmp;
int num, i;
stnode = (struct node *)malloc(sizeof(struct node));
if(stnode == NULL) {
printf(" Memory can not be allocated.");
}
else{
// キーボードから1番目のノードのデータを読み込む
printf(" Input data for node 1 : ");
scanf("%d", &num);
stnode->num = num;
stnode->nextptr = NULL;
tmp = stnode;
// n個のノードを作成し、リンクリストに追加する
for(i=2; i<=n; i++){
fnNode = (struct node *)malloc(sizeof(struct node));
if(fnNode == NULL) {
printf(" Memory can not be allocated.");
break;
}
else{
printf(" Input data for node %d : ", i);
scanf(" %d", &num);
fnNode->num = num;
fnNode->nextptr = NULL;
tmp->nextptr = fnNode;
tmp = tmp->nextptr;
}
}
}
}
void reverseDispList(){
struct node *prevNode, *curNode;
if(stnode != NULL){
prevNode = stnode;
curNode = stnode->nextptr;
stnode = stnode->nextptr;
prevNode->nextptr = NULL; // 先頭ノードを末尾ノードとして扱う
while(stnode != NULL){
stnode = stnode->nextptr;
curNode->nextptr = prevNode;
prevNode = curNode;
curNode = stnode;
}
stnode = prevNode; // 末尾ノードを先頭(ヘッド)として扱う
}
}
void displayList(){
struct node *tmp;
if(stnode == NULL){
printf(" No data found in the list.");
}
else{
tmp = stnode;
while(tmp != NULL){
printf(" Data = %d\n", tmp->num);
tmp = tmp->nextptr;
}
}
}
実行結果
上記のプログラムをコンパイルして実行すると、次のような出力が得られます。入力した順序とは逆の順序でデータが表示されていることが確認できます。
single Linked List : print it in reverse order : ------------------------------------------------------------------------------ Input the number of nodes : 5 Input data for node 1 : 12 Input data for node 2 : 45 Input data for node 3 : 11 Input data for node 4 : 9 Input data for node 5 : 10 Data entered in the list are : Data = 12 Data = 45 Data = 11 Data = 9 Data = 10 The list in reverse are : Data = 10 Data = 9 Data = 11 Data = 45 Data = 12
リスト反転の仕組み(ポイント解説)
reverseDispList関数では、stnode・curNode・prevNodeの3つのポインタを使いながらリストを先頭から走査し、各ノードのnextptrを「前のノード」へ向き直すことで反転を実現しています。
具体的には、まず先頭ノードのnextptrをNULLに設定して末尾ノードに変え、その後ループ処理で各ノードのリンクを逆向きにつなぎ替えます。ループが完了した時点で、元の末尾ノードを新しい先頭(ヘッド)としてstnodeに代入すれば、反転されたリストの完成です。この手法なら余分なメモリを消費せず、O(n)の計算量でリスト全体を反転できます。
-
【C言語】forループを使って1〜Nまでの素数をすべて表示するプログラム
問題 実行時にユーザーが入力した値nに対して、1からnの間に存在するすべての素数を表示するC言語プログラムを作成しましょう。 解決策 ここでは、forループを使用して、実行時にユーザーから与えられた値nまでの範囲内にある素数をすべて検出・表示する方法を解説します。なお、素数とは、1とその数自身以外に約数を持たない、1より大きい自然数のことです。具体的には、2、3、5、7、11、13などが該当します。 アルゴリズム 以下は、実行時にユーザーが入力した値nまでの素数をすべて表示するためのアルゴリズムです。 ステップ1 − nの値を入力として読み込む ステップ2 − カウンタ変数countを0で初
-
C言語で連結リストを使った優先度付きキューの実装方法
本記事では、整数値の「データ」と「優先度」が与えられたとき、指定された優先度に従って連結リスト(リンクリスト)を構築し、結果を表示する方法を解説します。 優先度付きキューとは キューはFIFO(First In, First Out:先入れ先出し)方式のデータ構造であり、最初に挿入された要素が最初に取り除かれます。 一方、優先度付きキュー(プライオリティキュー)は、要素の挿入・削除を「優先度」に基づいて行えるキューの一種です。キュー、スタック、連結リストなどのデータ構造を用いて実装でき、以下のルールに従って動作します。 優先度が最も高いデータ(要素)は、優先度が低いものよりも先に処理される。