はじめての C
「リンクリスト」リンクリストって 何なのだろう ?
リンクリストとは、要するに、それぞれの項目 - item - が その次を 指し示している、そんな項目が 集まった ものなんです。
|1| -> |2| -> |3| -> |4| -> |5| -> -
そのシーケンスは、番兵 - sentinel - と 呼ばれる 特別の 項目の 値を 最後尾に もっていて、多くの 場合では、シンプルな null ポインタが それに なります。
各々の 項目は ポインタを 伴った 構造体で、ポインタの 示す 先には 同じ型の "next" ポインタが あります。 ポインタが、全体の どこにあるかを 捜して 知らせるのです。
struct Item {
T data;
struct Item *next;
};単純だけど、1つの 方向に 進む - travel - だけなら、これで 十分です (first から 始まって last で 終わるような)。
でも、行きすぎてから、その項目まで 帰りたいときには、"prev" ポインタという 別の ポインタが 必要になります。
struct Item {
T data;
struct Item *prev;
struct Item *next;
};この構造体を 使うことで、前方にも 後方にも 進むことが できる、項目のリストを つくることが できます。
別の 言い方だと、全体の 中の それぞれの 項目が、どこに いても、手に 入るわけです。
簡単に 示してみましょう。
- <- |1| <- |2| <- |3| <- |4| <- |5| (prev)
1 -> 2 -> 3 -> 4 -> 5 -> - (next) まずい 図ですが、もし 読みとれるようでしたら、prev ポインタが next ポインタと 同じ 道のり - way - で 動くことに 注目してください。
例えば、リストの 最初の 項目の前に 番兵が あるとすると、prev ポインタの 最終点で それは 現れてきます。
リストの 中の どれかの 項目に アクセスする 際には、間接参照 - derefering - が 使えます。
次の 項目に 行く : item = item->next;
前の 項目へ 帰る : item = item->prev;
次の 次の 項目へ : item = item->next->next;
元にも 戻れる :p : item = item->next->prev;
ループを 用いるのも、たいていは 簡単です。
リストを 渡っていく 普通の 表現法は こんな 感じです。
for (item = list; item != NULL; item = item->next) {
visit(item); /* visit does something with a single item */
}とっても 簡単で、それに、 ちょうど C や C++ で、配列を 渡っていくとき 用いる もう 1つの 別の 表現法と 同じようなことに 気が つくでしょう。
for (i = 0; i < size; i++) {
visit(array[i]);
}