• Tidak ada hasil yang ditemukan

プログラミング演習Ⅲ Linked List

N/A
N/A
Protected

Academic year: 2024

Membagikan "プログラミング演習Ⅲ Linked List"

Copied!
32
0
0

Teks penuh

(1)

プログラミング演習Ⅲ Linked List

P. Ravindra S. De Silva

e-Mail:

(2)

Page 2

連結リストとは ?

A B C D ∅

一つひとつの要素がその前後の要素との参照関係をもつデータ構造

連結リストを使用する利点

-

通常の配列はサイズが固定されている

:

データの挿入や削除をしたい ときはデータを移動させる必要がある

連結リストならば必要なサイズ分だけ追加することができる

:

挿入や削 除をしてもデータを移動させる必要はない
(3)

単方向リスト

 単方向リストは、連続ノード からなるデータ構造の基本的 な概念である

 各ノードは次を格納する

要素

次のノードへのリンク

要素 ノード

A B C D ∅

(4)

Page 4

4

連結リストの実装

任意のデータフィールド群を持ち、

1

つか

2

つの参照(リンク)により次(お よび前)のノードを指している。

struct list {

int data;

struct list *next;

}

次を参照するポインタをリンクと呼ぶ。どの構造体も後続の領域へ導くリ ンクでつながる。この後続を参照するポインタは、メモリ内のそれぞれの 場所を示すアドレス、または特別な値

NULL

を含む。

data next

(5)

struct list {

int data;

struct list *next;

}

struct list a, b, c;

a.data = 1;

b.data = 2;

c.data = 3;

a.next = b.next = c.next = NULL;

b

a c

NULL

NULL 2 3 NULL

1

(6)

Page 6

例(つづき)

struct list {

int data;

struct list *next;

}

struct list a, b, c;

a.data = 1;

b.data = 2;

c.data = 3;

a.next = b.next = c.next = NULL;

a.next = &b;

b.next = &c;

b

a c

3 2

1

(7)

動的メモリ操作

struct node{

int data;

struct node *next;

};

struct node *ptr;

ptr = (struct node *) /*type casting */

malloc(sizeof(struct node));

data next ptr

(8)

Page 8

Free 操作

関数

free

はメモリを解放する- 換言すると、メモリをシステムに返すことで、将 来的にそのメモリを解放することができる

free(ptr);

ptr

?

(9)

連結リストのノード – 例

 3

つのデータ領域をもったノード:

struct student{

char name[20];

int id;

double grdPts;

struct student *next_student;

}

Name id grdPts next_student

(10)

Page 10

連結リストの基本的な操作

ノードを追加する

ノードを削除する

ノードを検索する

リストの走査 : カウント処理や統計的な処理に便利
(11)

空の連結リストにノードを追加する

処理前

:

pNew -> next = pHead; //

リンクを設定

NULL pHead = pNew;// point list to first node

処理後

:

39 pNew

pHead

pPre

39 pNew

pHead

(12)

Page 12

連結リストの先頭にノードを追加する

処理前

:

処理後

:

39 pNew

pHead

pPre

75 124

39 pNew

pHead

pPre

75 124

pNew -> next = pHead;

pHead = pNew; //

先頭ノードのリストを参照
(13)

連結リストの中間にノードを追加する

処理前 :

pNew -> next = pPre -> next;

pPre -> next = pNew;

処理後 :

64 pNew

pPre

55 124

64 pNew

55 124

(14)

Page 14

連結リストの終端にノードを追加する

処理前 : pNew -> next = NULL;

pPre -> next = pNew;

処理後 :

144 pNew

pPre

55 124

pNew 144

pPre

55 124

(15)

連結リストにノードを挿入する

先 頭

(pHead)

と 前

(pPre)

の ポ イ ンタ を与 え て、 データ が 挿 入 さ れ る

(item).

新しいノードのためのメモリが確保され

(pNew)

、リンクが適切につながる。

//連結リストにノードを挿入する struct node *pNew;

pNew = (struct node *) malloc(sizeof(struct node));

pNew -> data = item;

if (pPre == NULL){

//先頭ノードの前に追加する もしくか 空の場合 pNew -> next = pHead;

pHead = pNew;

}

else {

//中間か終端に追加する

pNew -> next = pPre -> next;

(16)

Page 16

連結リストからノードを削除する

いくつかのリンクを変更しリストからノードを理論的に取り除くことで、リ ストから物理的にノードを削除することができる

リスト中の任意のノードを削除することができる。リスト中のノードを削除 して空のリストとなった場合は、先頭ポインタはヌルに設定される。

理論的にノードを削除する

:

消したいノード

(pCur)

とその前にあるノード

(pPre)

を考える

.

前のノードのリンクの指し示すノード

(pPre->next)

を,消したいノードの次の ノード

(pCur -> next)

にする.

– free

関数を使って消したノードの領域を解放する.
(17)

連結リストから一番目のノードを削除する

処理前

: pHead = pCur -> next;

free(pCur);

処理後

:

pHead

pPre

75 124

pCur

pHead

pPre

Recycled 124

pCur

(18)

Page 18

連結リストからノードを削除する – 一般的な場合

処理前

: pPre -> next = pCur -> next;

free(pCur);

処理後

:

75 96 124

pPre pCur

75 Recycled 124

pPre pCur

(19)

連結リストからノードを削除する

ノードの先頭

(pHead)

,消したいノード

(pCur),

消したいノードの一つ前

のノード

(pPre)

を用意する.

pCur

を消し,

pCur

の為に確保された領域を

解放するという処理は,以下のようになる.

//

連結リストからノードを削除する

if (pPre == NULL)

//

リストの最初のノードだった場合の削除

pHead = pCur -> next;

else

//

リストの最初のノード以外の場合の削除

pPre -> next = pCur -> next;

free(pCur).

(20)

Page 20

連結リストの検索

連結リストの挿入や削除の操作はどちらも,特定の,挿入先のノードや消したい データに一致するノードを検索しなければならない.

//連結リストからノードを検索する pPre = NULL;

pCur = pHead;

//目的の値が見つかるまで、あるいはデータの終端にたどり着くまで繰り返す while (pCur != NULL && pCur -> data != target) {

pPre = pCur;

pCur = pCur -> next;

}

//目的の値が見つかったら、あるいはデータの終端に来たらどうするか if (pCur != NULL)

found = 1;

else

found = 0;

(21)

連結リストの走査

リストの走査はリストにある全てのデータを処理する.したがって,全て のノードにあるデータは処理される.

//

連結リストの走査

Struct node *pWalker;

pWalker = pHead;

printf(“

リストに含まれているのは

:¥n”);

while (pWalker != NULL){

printf(“%d ”, pWalker -> data);

pWalker = pWalker -> next;

}

(22)

Page 22

応用

(23)

多項式

 一つの連結リストで表される多項式 以下の多項式を表現したい

A x ( ) = a m − 1 x e

m1

+ a m − 2 x e

m2

+ + ... a x 0 e

0

• 以下のような 0 でない係数 a

i

と負でない乗数 e

i

の場合 … e

m-1

> e

m-2

> … > e

1

> e

0

≧ 0.

– それぞれの項を係数と乗数,次の項へのポインタを含むノード

として表す.

(24)

Page 24

宣言

typedef struct poly_node *poly_pointer;

typedef struct poly_node { int coef;

int expon;

poly_pointer link;

};

poly_pointer a, b, c;

coef expon link

A x ( ) = a m − 1 x e

m1

+ a m − 2 x e

m2

+ + ... a x 0 e

0
(25)

例:多項式を表現する

a = 3 x 14 + 2 x 8 + 1

3 14 2 8 1 0

a null

b = 8 x 14 − 3 x 10 + 10 x 6

(26)

Page 26

多項式の加算

 二つの多項式を足すには,多項式aと多項式bで示されているノー ドで始まるそれぞれの項を調べる.

 二つの項の乗数が等しい場合,二つの係数を足し,結果の多項 式に新しい項を作る.

 今調べているaの項の乗数が,bの項の乗数よりも少ない場合,b

の項を複製し,結果の多項式に加える.そして,bの項を次の項へ

進める.(a->expon > b->expon の場合も,同様に行う.)

(27)

例:多項式の加算

 (a) a->expon == b->expon

3 14 2 8 1 0

a

8 14 -3 10 10 6

b 11 14

d a->expon == b->expon

(28)

Page 28

例:多項式の加算

 (b) a->expon < b->expon

3 14 2 8 1 0

a

8 14 -3 10 10 6

b 11 14

d -3 10

a->expon < b->expon

(29)

例:多項式の加算

 (c) a->expon > b->expon

3 14 2 8 1 0

a

8 14 -3 10 10 6

b

11 14 -3 10 2 8

(30)

Page 30

サンプルコード

 Program 4.10 : 2つの多項式を加算する

 poly_pointer padd(poly_pointer a, poly_pointer b) {

poly_pointer front, rear, temp;

int sum;

rear =(poly_pointer)malloc(sizeof(poly_node));

if (IS_FULL(rear)) {

fprintf(stderr, “The memory is full¥n”);

exit(1);

}

front = rear;

while (a && b) {

switch (COMPARE(a->expon, b->expon)) {

(31)

サンプルコード(つづき)

case -1: /* a->expon < b->expon */

attach(b->coef, b->expon, &rear);

b= b->link;

break;

case 0: /* a->expon == b->expon */

sum = a->coef + b->coef;

if (sum) attach(sum,a->expon,&rear);

a = a->link; b = b->link;

break;

case 1: /* a->expon > b->expon */

attach(a->coef, a->expon, &rear);

a = a->link;

} }

for (; a; a = a->link) attach(a->coef, a->expon, &rear);

for (; b; b=b->link)attach(b->coef, b->expon, &rear);

rear->link = NULL;

temp = front; front = front->link; free(temp);

return front;

(32)

Page 32

サンプルコード

for (; a; a = a->link) attach(a->coef, a->expon, &rear);

for (; b; b=b->link)attach(b->coef, b->expon, &rear);

rear->link = NULL;

temp = front; front = front->link; free(temp);

return front;

}

余分な先頭ノードを削除する

Referensi

Dokumen terkait

電 気 電 子 無線工学 Radio Communication Engineering (選択 2 単位) 1年前期 畑迫健一 E-ENC103 授業テーマ・内容 情報技術の発展にしたがい、情報通信が果たす役割がますます広がってきています。なかでも、電波をなかだちにする無線通信の

B(良)評価 ①ビジネス文書作成のために必要な操作機能(書式設定、 文書削除・挿入、移動・コピー、表作成、文字加工・装 飾、印刷)全般において、正しく操作することができ、実 技試験で、時間内に指示どおりのことが80%できている。 ②15回の授業終了までに、10分間のタイピング正解文 字数が350字以上である。 ③ 日本語ワープロ検定試験3級にチャレンジする。

プログラミング応用 練習問題(5/5) 2005/01/27 名列番号 氏名 問8. 以下の関数を作成せよ。 10 (1) 配列とそのサイズおよび、配列の最大値と最小値を求めた結果を返すための変数のアドレスを 受け取り、配列に保存されたデータの最大値と最小値を求めて返す関数 (2) 2つの数値の合計と平均を一度に求める関数... プログラミング応用 練習問題

次回までの宿題 考えてくること 1 二分木と限らず 木構造を持つと見るべきデータの具体例を、 身の回りで探せ。 2 例えば、3+4*2 とか 3*4+2 とかのように、 二項演算子で書かれた式は、 内在的に二分木の構造を持っている。 それを図に表せ。 また、その式の値を計算するには どうしたらよいか。... 二分木の型定義 typedef struct

Laurent展開の例をいくつかあげる。極とその位数の判定法を学ぶ零点とその位 数の特徴づけと関連が深いし、似ているところも多い、混同しないこと。留数を求 める話もいくつか出てくる。 宿題12を出します。 宿題のうち、〆切は過ぎたけれどまだ解説していないものについては、今週中に WWWで解答を発表します。フィードバックも順次行います。 かつらだまさし...

問題 131 1pt X×Y, dを問題115で定めた直積距離空間とする。f:X×Y →Xをfx, y =x で定めると、連続であることを示せ。 問題 132 1pt もし写像f:X →Y が、あるC >0に対してdYfx, fy≤CdXx, yをみた すとすれば、fは連続であることを示せ。 問題 133 1pt

もし単射な写像f: X →Y と単射な写像g:Y →X が存在 すれば,全単射な写像h: X→Y が存在すること§ を示せ.. 写像f:X →Y が連続であるとは,「もしXの点列 {xn}n∈Nがxに収束していれば,Y

1 気象学のための数学 1 一次変換 太陽のような天体の方位や高度は、時刻や季節、観測地点の緯度によって変化する。時 刻や緯度などを与えて天体の方位、高度を計算するということは、天の北極や天の赤道を 基準に表されていたベクトルを、天頂や水平線を基準に表されるベクトルに変換すること