PPT for 20080514

Download Report

Transcript PPT for 20080514

データ構造とアルゴリズム
第4回
リスト
~ データ構造(1)~
1
前回の問題

問題 以下の4個のメンバーから構成される構造体を
定義せよ。型名をIMAGEとする。
・整数値の番号 n
・ローマ字タイトル name
・実数値の平均輝度 avL
・次のIMAGE型構造体へのポインタ next
2
前回の問題の解答
struct IMAGE{
int n;
char name[20];
double avL;
struct IMAGE
*next;
};
多かった間違い
第1位
第2位
char name;
⇒
セミコロン無し
正答率=41%
簡単すぎるかと反省してたので、
ちょっとビックリでガッカリ
文字数を指定して
文字列にする!
char name[20];
3
本日の内容

リスト

抽象データ型としてのリスト

配列によるリストの実現

連結リストによるリストの実現
7
基本的な抽象データ型
3つとも情報関連の資格試
験に頻出する.重要なので
よく理解しておくこと.

(List)

リストの特殊なケース
(Stack)
(Queue, 待ち行列)


D
C
B
A
D C B A
8
リストの数学的表現

(p.26~)
リスト:
線形リスト(linear list)と呼ぶこともある.



ai :
n :
n=0
a0,a1, a2, …, ai-1, ai, ai+1, … , an-1
最後の要素
最初の要素
9
抽象データ型としてのリスト

抽象データ型:
リスト
操作
要素を
並べたもの
10
表記法についての説明



L
p
x
: リスト
:位置を表わす変数
:挿入したいデータ
要素の型はすべて同じであれば
よい.
教科書ではelememttype型とし
ている.
x
L
a0
a1
p
…
ai-1
n
ai
…
an-1
11
代表的なリスト操作
 INSERT(x, p, L)
新要素の挿入
 DELETE(p, L)
要素の削除
 LOCATE(x, L)
要素xの位置を探す
 RETRIEVE(p, L)
 FIND(i, L)
位置pにある要素を返す
i番目の要素を返す
 TOP(L)、LAST(L)
先頭、末尾の位置を返す
 NEXT(p, L)、PREVIOUS(p, L)
 CREATE(L)
pの直前、直後の位置を返す
新規に空リストLを作成する
12
INSERT(x, p, L)
p
L
A
B
C
D
x
F
G
E
H
p
L
A
B
C
D
13
DELETE(p, L)
p
L
A
B
C
D
E
F
G
H
p
L
A
B
C
D
E
F
G
H
14
LOCATE(x, L)
x
L
A
B
C
D
F
D
G
H
配列のインデクスなら[3]
ポインタならば、ここを指すポインタ
15
RETRIEVE(p, L)
p
L
A
B
C
D
F
G
H
16
FIND(i, L)
i = 3のときは?
L
A
B
C
D
F
G
H
17
TOP(L) と LAST(L)
TOP(L)
LAST(L)
L
A
B
C
D
F
G
H
18
NEXT(p,L)とPREVIOUS(p,L)
NEXT(p, L)
PREVIOUS(p, L)
p
L
A
B
C
D
F
G
H
19
CREATE(L)
CREATE(L)
空リストの先頭の位置が返る
L
20
リストの実現(実装)
すべての操作が常に必要になるとは限らない
 すべての操作を効率よく実行できるデータ構造の実
現は困難
⇒プログラムの実装の際には,
を採用する


リストの実現に使用できるデータ構造


配列
連結リスト(linked list)

ポインタを用いてデータ間の関係を表現したデータ構造
Insert,Deleteの実現方法の例を説明する
21
配列によるリストの実現
例) int a[MAXLENGTH];
a[0]
a[1]
last
5
10
リスト
MAXLENGTH 個
22
空
a[MAXLENGTH-1]
23
Insert(x, p, L)
x
A
p
last
2
[0]
B
[1]
L
[2]
L
[3]
p
last
2
② 3
[0]
B
[1]
A ③
[2]
L
[3]
L
[4]
[4]
[5]
[5]
①
24
Delete(p, L)
last
4
[0]
E
[1]
X
[2]
E
[3]
I
①
last
3
[4]
T
4
[5]
p
[0]
E
[1]
X
[2]
EI
[3]
TI
[4]
T
p
②
[5]
25
配列で実現する場合の注意点
last
2
[0]
E
[1]
I
[2]
T
p
[3]
[4]
[5]
[6]
lastがMAXLENGTH – 1の場合,リストは満杯
(これ以上,要素を挿入できない)
26
mallocの復習
malloc(n);

メモリ上に

普通、n には
28
mallocの使用例
struct ITEM{
int
element;
struct ITEM
*next;
};
ptr = (struct ITEM*)malloc(sizeof(struct ITEM));
 メモリ空間上に、
 mallocは
ptr
?
?
29
メモリ空間上のイメージ
番地
mallocするのか。
それじゃ、ここがstruct
ITEMの分確保できるから、
ここをつかうぞ。
00000000
内容
FF1F0204
00000004
00000008
0000000C
0CFFFF1A
00000010
FF001121
ptrが格納されている場所 00000128
00000004
00000004番地を使うことを
ptrにメモしておこう。
30
値を返すとは?(2週目のスライド再掲)
関数triangle
を呼び出す
メインプログラム
S = triangle(5, 7);
(Sに17.5が代入される)
関数
float triangle(int L, int H){
return L*H/2.0;
}
(5*7/2.0=17.5)
計算結果を
関数の呼び出し元に返す
31
ポインタを返すとは?
関数LAST君、末尾のセルは
どこか調べてね
メインプログラム
関数
struct cell* LAST (struct cell* init){
リストの末尾の位置を探す;
return 末尾へのポインタ;
}
pt = LAST(init);
pt にアドレス 0104が
代入される
末尾のセルは
0104番地にありますよ
32
復習 ドット演算子 .
struct SAMPLE{
int
width;
int
height;
};
data1
width
int main(void)
{
struct SAMPLE data1;
50
height
data1.width = 50;
…
return 0;
}
構造体のメンバにアクセスする
ときは、ドット演算子を使って、
メンバ名を指定する。
33
復習
int main(void)
{
int a=5, b;
int *pt;
pt = &a;
間接演算子 *
a
5
pt
b
5
b = *pt;
…
return 0;
}
34
構造体へのポインタのときは?
int main(void)
{
struct SAMPLE data1;
struct SAMPLE *pt;
pt = &data1;
pt
data1.width
(*pt).width
pt->width
data1.width
data1.height
(*pt).width = 50;
…
return 0;
}
35
ポインタによるリストの実現
init
ここではポインタのみになっているが、実
装を簡単にするため、ヘッダも完全なセ
ルにすることもある.
a0
a1
a2
an-1
36
例)整数のリスト(単方向リスト版)

型定義
struct CELL {
int
element;
struct CELL *next;
};
init
a0
CELL型
要素(element)と
次のセルを指すポインタからなる
a1
a2
an-1
37
Insert(x, p, L)
init
p
A
B
C
x
38
Insert(x, p, L)の実現(1)
init
p
A
重要!!
教科書p.30のソースと
よく見比べて理解すること
B
C
39
Insert(x, p, L)の実現(2)

リストの途中への挿入の場合
init
p
A
B
C
r
40
Insert(x, p, L)の実現(3)

リストの途中への挿入の場合
init
p
q
A
B
C
r
41
Insert(x, p, L)の実現(4)
init
p
q
A
B
C
r
42
Insert(x, p, L)の実現(5)
init
r
p
q
A
B
C
x
43
先頭へのInsert

②、③が異なる
p (先頭への挿入のときpはNULL)
init
③
init = r ;
r
② q = init;
A
B
C
44
Delete(p, L)
init
p
③ free(q);
A
B
C
D
45
双方向リスト

「要素」と「次のセルを指すポインタ」, 「前のセルを指すポ
インタ」で構成される連結リストは,


長所:
短所:
ap-1
ap
ap+1
46
例)整数のリスト(双方向リスト版)

型定義
前の要素を指す
ポインタが増えた
struct CELL {
int
element;
struct CELL *next;
struct CELL *previous;
};
ap-1
ap
ap+1
47
計算量の比較
データ構造
INSERT, DELETE
配列
単方向リスト
last
2
[0]
[1]
[2]
[3]
[4]
[5]
[6]
E
I
T
FIND, LAST, PREVIOUS
p
init
p
E
I
T
48
メモリの使用効率に関する比較
データ構造
リストの最大長
余分に必要になるメモリ
配列
単方向リスト
last
2
[0]
[1]
[2]
[3]
[4]
[5]
[6]
E
I
T
p
init
p
E
データが
入っていない
I
T
ポインタ用の空間
49
本日の問題
の様に連結されている時、下の番地表での連結を矢印で示せ。
一つのセルは連続した2つの番地に入っているとする。
ROOT
0093
0091
番地
内容
0094
009D 0000
番地
0106
内容
0093
番地
010E
内容
0095
0108
010F
010A
0110
0096
ROOT 00FF
0100
0107
0100
0091
0108
0101
0106
0109
010E
0111
0112
0102
009C
010A
009A
0112
0098
0103
0104
010B
010C
0113
0114
0104
009D
010C
009B
0114
0099
0105
0000
010D
0102
0115
0000 50