線形連結リスト
配列
• リストの途中への追加,削除は困難
データ 4 データ 3.5 データ 5 データ 4
0 データデータデータ 123 N
データ 5
← データ 3.5
線形連結リスト (Linked List)
• 各要素をポインタで結合
• 先頭から順に参照
• 配列の要素番号のようなインデックスはない
• 「何番目のデータ」というランダムアクセスは不可
5 3 8 2
線形連結リスト (Linked List)
struct cell { int value;
struct cell *next;
};
•
セル• データ,及び,次の要素の格納場所を 示すポインタで構成
• 最後のデータの,次を示すポインタは NULL
セル
v a lu e p o i n t e r
線形連結リスト (Linked List)
struct cell { int value;
struct cell *next;
};
c e l l 0 x e f f f 9 2 0 2 3
0 x e f f f 9 2 8 0 x e f f f 9 2 8 3 5
0 x e f f f 9 3 0
0 x e f f f 9 3 0 4 8 N U L L
2 3 3 5 4 8
0 x e f f f 9 2 0 0 x e f f f 9 2 8 0 x e f f f 9 3 0
( N U L L )
セルの挿入
セルを挿入する関数
• 挿入する位置を示すポインタ型変数へのポインタと
,格納する値を引数とする.
※ ポインタ自身を変更する必要があるため
void insert_cell(struct cell
**pointer, int new_value)
セルを挿入する関数
1.新たなセルを用意し,値 (value) を代入
new_cell=(struct cell *)malloc (sizeof(struct cell));
new_cell->value=new_value;
セルを挿入する関数
2. 新たなセルの次へのポインタに,元の場所へのポ インタをコピー
new_cell->next=*pointer;
( N U L L ) c o p y
( N U L L ) n e w _ c e l l
n e w _ c e l l
セルを挿入する関数
3. 元のポインタの値を新たなセルに変更
*pointer=new_cell;
( N U L L )
( N U L L ) n e w _ c e l l
n e w _ c e l l c h a n g e
セルの挿入
struct cell *head=NULL, **p;
p=&head;
while(…) {
insert_cell(p,data);
p=&((*p)->next);
}
• 引数
• 挿入場所のアドレスを格納している 変数のアドレス
• つまり,前のセルの次へのポインタ が格納されている変数 (next) のアド レス
セルの削除
セルを削除する関数
• 削除するセルへのポインタ型変数へのポインタを引 数とする.
• つまり,前のセルの,次のセルへのポインタのアドレス
※ ポインタ自身を変更する必要があるため
void delete_cell(struct cell **pointer)
セルを削除する関数
1. 削除したいセルへのポインタを求め,元のポイン タの値を,削除するセルの後のセルに変更
target=*pointer;
*pointer=target->next;
( N U L L ) t a r g e t
c o p y
( N U L L ) t a r g e t
セルを削除する関数
2. セルを削除
free(target);
( N U L L ) t a r g e t
( N U L L ) d e l e t e
循環・重連結リスト
循環リストと重連結リスト
• 循環リスト( circular list )
重連結リスト( doubly linked list )
循環・重連結リスト
dummy
空の循環・重連結リスト
循環・重連結リスト
• ノードの挿入
ノードの削除
* (p->left) * p
* q
q p
* p
循環・重連結リスト
・関数 insert_cdl_list を実行
・初期状態
問題1
・再度,関数 insert_cdl_list を 実行した結果を答えなさい.
・解答
問題2
・関数 insert_left を実行した 結果を答えなさい.
・解答