個人的にしっくりこない所があり,悪い所/改善点が知りたいので指摘と修正をお願いします。
Webで調べてもC言語のものばかりで,Cをやっていないので読みづらい部分も多く(typedef struct {} name など)
理論は分かっていたので読み解く前に作ることにしました。(C++のものも一つあったがかなり本格的な双方向リストだったため)
#include <iostream>
#include <cstdlib> // NULL
// 簡単な単連結リストの実験
class Node
{
private:
int value; // ノードの保持する値
Node* next; // 次の要素へのポインタ。初期値NULL
public:
// コンストラクタ
Node(int n) : value(n), next(NULL) {};
int GetValue() { return value; }
Node* GetNextNode() { return next; }
void SetNextNode(Node* nextnode) { next = nextnode; }
bool isLast() { return next == NULL ? true : false; }
};
class List
{
private:
Node* head;
public:
// コンストラクタ。
List() : head(NULL) {}; // 最初は次が何もない状態
// リストの最後尾に新ノードを追加する
void AddNode(int num)
{
Node* finder = head; // Node型を扱うポインタにリストの先頭アドレスを入れる。
while(head != NULL && !finder->isLast())
{
finder = finder->GetNextNode(); // リストの最後にあるNodeにfinderを合わせる
}
if(head != NULL)
finder->SetNextNode(new Node(num)); // 最後のノードの最後尾に新しいノードをセット。
else
head = new Node(num);
}
// リストの要素を先頭から出力する
void OutputNodes()
{
Node* n = head;
while(true)
{
std::cout << n->GetValue() << std::endl;
n = n->GetNextNode();
if(n == NULL)
break;
}
}
// デストラクタ
~List()
{
Node* finder = head;
Node* temp;
while(true)
{
temp = finder->GetNextNode(); // 次の要素へのポインタを記憶
delete finder; // 現在選択中のポインタをdelete
finder = temp; // 次の要素へ移行
if(finder == NULL) // 次の要素がない場合
break;
}
}
};
int main()
{
using namespace std;
List list; // リスト作成
cout << "-1と入力するまでリストに整数値を格納し続けます" << endl;
int a = 0;
while(true)
{
std::cin >> a;
if(a == -1)
break;
else
list.AddNode(a);
}
cout << "リストの値を全て出力します" << endl;
list.OutputNodes();
return 0;
}
前者のは.isLast()でwhile文をまわした場合,最後のNodeに処理がいきません。(do whileは使わない方針でお願いします)
そのためwhile(true)を通してstd::coutなりdeleteしたあと,break;しました。
後者はListに要素が一つもない時,finder->isLast()で落ちるためです。
※
全く関係のない話ですが,この上のコードをコピペした後,文字を書き換えようとすると書き込み欄のスクロールバーが暴れてまともにかけないのですが
原因は分かりませんか・・・?
※2
spoilerを表示,はどのようなタグを使えばいいのでしょう?[spoiler]ではないようで。