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

C++で循環片方向リンクリストから最小値と最大値を求める方法

本記事では、C++を使って循環片方向リンクリスト(単一循環リンクリスト)から最小値と最大値を検索する方法を解説します。

循環リンクリストの基本構造

循環リンクリストは、最後のノードのnextポインタが先頭ノードを指すデータ構造です。これにより、リスト全体がリング状につながります。また、startポインタによって先頭ノードの位置も管理されます。

新しい要素を挿入するときは、末尾ノードのnextに新ノードをつなぎ、新ノードのnextにstartノードのアドレスを設定します。これで循環構造が維持されます。

最小値・最大値を求めるアルゴリズム

考え方はとてもシンプルです。手順は以下の通りです。

  • 変数 minINT_MAX(int型の最大値)で、maxINT_MIN(int型の最小値)で初期化します。
  • リストを先頭から順に走査します。
  • 現在の要素が min より小さければ min を更新し、max より大きければ max を更新します。
  • 走査が終わった時点で、min には最小値、max には最大値が格納されています。

この手法の計算量は O(n) で、リストを一度走査するだけで両方の値を取得できます。

C++による実装例

#include<iostream>
using namespace std;
class Node{
    public:
    int data;
    Node *next;
};
Node* getNode(int key){
    Node *newNode = new Node();
    newNode->data = key;
    newNode->next = NULL;
    return newNode;
}
void insert(Node **start, int data){
    Node *current = *start;
    Node *newNode = getNode(data);
    if(*start == NULL){
        newNode->next = newNode;
        *start = newNode;
        return;
    }
    while (current->next != *start) {
        current = current->next;
    }
    newNode->next = *start;
    current->next = newNode;
}
void displayList(Node *start){
    Node* current = start;
    if (start == NULL) {
        cout << "Display List is empty";
        return;
    } else {
        do {
            cout << current->data << " ";
            current = current->next;
        }
        while (current != start);
    }
    cout << endl;
}
void getMinMax(Node **start){
    if(*start == NULL){
        return;
    }
    Node* current;
    current = *start;
    int min = INT_MAX, max = INT_MIN;
    do {
        if (current->data < min) {
            min = current->data;
        }
        if (current->data > max) {
            max = current->data;
        }
        current = current->next;
    } while (current != *start);
    cout << "Minimum: " << min << ", Maximum: " << max;
}
int main() {
    int data[] = {99, 11, 22, 10, 44, 55, 66};
    int n = sizeof(data)/sizeof(data[0]);
    Node *start = NULL;
    for(int i = 0; i<n; i++){
        insert(&start, data[i]);
    }
    displayList(start);
    getMinMax(&start);
}

実装上のポイント: 循環リンクリストの走査では、while (current->next != start) のような条件にすると最後のノードが比較対象から漏れてしまうことがあります。do-while 文を使えば、全ノードを確実に1回ずつ処理できるため安全です。

出力結果

99 11 22 10 44 55 66
Minimum: 10, Maximum: 99

このように、循環リンクリストでも通常の線形リストと同様に、一度の走査で最小値と最大値を効率的に求めることができます。

  1. 【C++】連結リスト内で指定した数Kで割り切れる最大要素と最小要素を求める方法

    連結リストとは 連結リスト(リンクリスト)は、要素同士がポインタで連結された線形データ構造です。各要素(ノード)は「データ部分」と「次の要素を指すリンク(ポインタ)」を持ち、メモリ上の連続していない場所に配置されることもあります。 本記事では、データ部分と次ノードへのリンクを持つ片方向連結リストと、整数Kが与えられます。目的は、連結リスト内の要素のうち「Kで割り切れる」要素の最大値と最小値を見つけることです。線形連結リストは一方向にしか走査できないため、ヘッド(先頭)ノードから順に各ノードを訪問し、そのデータ部分がKで割り切れるかどうかを判定します。現在のノードの値が、それまでに見つかった最

  2. C++で循環リンクリストのノード数をカウントする方法

    ノードから構成される循環リンクリスト(Circular Linked List)が与えられ、そのリスト内に存在するノードの総数を求めるのが課題です。 循環リンクリストとは、連結リストの一種であり、最初の要素が最後の要素を指し、最後の要素が最初の要素を指すという特徴を持つデータ構造です。片方向リンクリスト(Singly Linked List)でも双方向リンクリスト(Doubly Linked List)でも、この循環リンクリストとして実装することが可能です。 以下のプログラムでは、片方向リンクリストを循環リンクリストとして実装し、その中に含まれるノード数をカウントする方法を紹介します。 具体