アルゴリズムとデータ構造1...new_element1->next = next_element1; //...

18
アルゴリズムとデータ構造 アルゴリズムとデータ構造1 アルゴリズムとデータ構造 アルゴリズムとデータ構造1 2008 2008627 27酒居敬一 酒居敬一(sakai.keiichi@kochi [email protected] tech.ac.jp ) http:// http://www info kochi www info kochi-tech ac jp/k1sakai/Lecture/ALG/2008/index html tech ac jp/k1sakai/Lecture/ALG/2008/index html http:// http://www.info.kochi www.info.kochi-tech.ac.jp/k1sakai/Lecture/ALG/2008/index.html tech.ac.jp/k1sakai/Lecture/ALG/2008/index.html

Upload: others

Post on 05-Aug-2020

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: アルゴリズムとデータ構造1...new_element1->next = next_element1; // リストのデータ構造// Java言語でアクセッサなし // El t2 t l t2 // どこかで 与

アルゴリズムとデータ構造アルゴリズムとデータ構造11アルゴリズムとデータ構造アルゴリズムとデータ構造11

20082008年年66月月2727日日

酒居敬一酒居敬一(([email protected]@kochi--tech.ac.jptech.ac.jp))

http://http://www info kochiwww info kochi--tech ac jp/k1sakai/Lecture/ALG/2008/index htmltech ac jp/k1sakai/Lecture/ALG/2008/index htmlhttp://http://www.info.kochiwww.info.kochi--tech.ac.jp/k1sakai/Lecture/ALG/2008/index.htmltech.ac.jp/k1sakai/Lecture/ALG/2008/index.html

Page 2: アルゴリズムとデータ構造1...new_element1->next = next_element1; // リストのデータ構造// Java言語でアクセッサなし // El t2 t l t2 // どこかで 与

待ち行列(FIFO)(44ページ)待ち行列(FIFO)(44ペ ジ)

データ挿入 データ取得デ タ挿入 デ タ取得

待ち行列(データの挿入・取得)

Page 3: アルゴリズムとデータ構造1...new_element1->next = next_element1; // リストのデータ構造// Java言語でアクセッサなし // El t2 t l t2 // どこかで 与

待ち行列の配列による実現待ち行列の配列による実現

データ挿入 データ取得デ タ挿入 デ タ取得

新しい要素を入れようとすると入らない→右へコピーして移動→隙間を空ける→隙間を空ける

Page 4: アルゴリズムとデータ構造1...new_element1->next = next_element1; // リストのデータ構造// Java言語でアクセッサなし // El t2 t l t2 // どこかで 与

リングバッファ(46ページ)リングバッファ(46ペ ジ)

配列の最初と最後を接続して環にしたもの

のポインタでデ タの出し入れを管理2つのポインタでデータの出し入れを管理

データの先頭を指すポインタ

head, frontデータの最後尾を指すポインタデ タの最後尾を指すポインタ

tail, rear2つのポインタが重なったらデータは空2つのポインタが重なったらデータは空

領域の大きさをnとしたらポインタの位置はnとおりデ タの数が0から まで 1とおりあるデータの数が0からnまでn+1とおりあるポインタが重なったら、空か満杯の状態が重なる…

Page 5: アルゴリズムとデータ構造1...new_element1->next = next_element1; // リストのデータ構造// Java言語でアクセッサなし // El t2 t l t2 // どこかで 与

リングバッファリア

挿入口リア

•環状のデータ格納領域デ タ 存在を すポ タ•データの存在を示すポインタ

取り出し口

フロント

Page 6: アルゴリズムとデータ構造1...new_element1->next = next_element1; // リストのデータ構造// Java言語でアクセッサなし // El t2 t l t2 // どこかで 与

満杯になったとき、リアとフロントのポインタが

重なってしまって

フロントリア リア

重なってしまって空と区別が付かない

Page 7: アルゴリズムとデータ構造1...new_element1->next = next_element1; // リストのデータ構造// Java言語でアクセッサなし // El t2 t l t2 // どこかで 与

配列を使用したリングバッファ配列を使用したリングバッファ

配列には始まりと終わりがある配列には始まりと終わりがある

ポインタが終わりまで移動したら先頭へ戻る

(フロント-リア)の演算でも境界を考慮

ラップラウンド処理ラップラウンド処理

ラップラウンド処理ラップラウンド処理

条件文で判定

配列の大きさを2のべき乗にする配列のインデックスをビットごとのAND処理

Page 8: アルゴリズムとデータ構造1...new_element1->next = next_element1; // リストのデータ構造// Java言語でアクセッサなし // El t2 t l t2 // どこかで 与

public class Queue{

private Queue(){}}public Queue(int aMaxSize){

int realSize = aMaxSize + 1;int realSize = aMaxSize + 1;this.maxSize = realSize;this.queueArray = new Object[realSize];this front = 0;this.front = 0;this.rear = 0;

} •データのおき場所は配列•front rearというポインタで管理

private int front;private int maxSize;

•front, rearというポインタで管理•キューの容量はmaxSizeで管理

private Object[] queueArray;private int rear;

}}

Page 9: アルゴリズムとデータ構造1...new_element1->next = next_element1; // リストのデータ構造// Java言語でアクセッサなし // El t2 t l t2 // どこかで 与

public Object dequeue(){

if(this.isEmpty()){System.err.println("待ち行列は空です");return null;;

}

Object dequedObject = this queueArray[this front];Object dequedObject = this.queueArray[this.front];this.queueArray[this.front] = null;++this.front;if(this maxSize == this front){if(this.maxSize == this.front){

this.front = 0;}

t d dObj t•frontの指すところがキューの先頭•先頭と最後尾が同じ場合は空return dequedObject;

}public boolean isEmpty()

•先頭と最後尾が同じ場合は空•条件文でラップラウンド処理

{return (this.rear == this.front);

}}

Page 10: アルゴリズムとデータ構造1...new_element1->next = next_element1; // リストのデータ構造// Java言語でアクセッサなし // El t2 t l t2 // どこかで 与

public boolean enqueue(Object aTarget){

if(this.isFull()){System.err.println("待ち行列はいっぱいです");return false;f ;

}this.queueArray[this.rear] = aTarget;++this rear;++this.rear;if(this.maxSize == this.rear){

this.rear = 0;} の指すところがキ の最後尾}return true;

}

•rearの指すところがキューの最後尾•先頭と最後尾が同じ場合は空

•そうならないようにする判定が必須public boolean isFull(){

そうならないようにする判定が必須•条件文でラップラウンド処理

return ((this.rear + 1) == this.front);}

Page 11: アルゴリズムとデータ構造1...new_element1->next = next_element1; // リストのデータ構造// Java言語でアクセッサなし // El t2 t l t2 // どこかで 与

public void printAll(){

System.out.println("待ち行列の内容");y p ( )if(this.isEmpty()){

System.out.println();return;

•場合分けしてラップラウンド処理•frontから配列終わりまでの表示}

int count = 1;int position = this.front;i li i ( hi f hi )? hi Si hi

•frontから配列終わりまでの表示•配列先頭からrearまでの表示

int limit = (this.front > this.rear)? this.maxSize: this.rear;while(position < limit){

System.out.println(count +"¥t" + this.queueArray[position]);t++count;

++position;}position = 0;position = 0;limit = (this.front > this.rear)? this.rear: 0;while(position < limit){

System out println(count +"¥t" + this queueArray[position]);System.out.println(count + ¥t + this.queueArray[position]);++count;++position;

}}System.out.println();

}

Page 12: アルゴリズムとデータ構造1...new_element1->next = next_element1; // リストのデータ構造// Java言語でアクセッサなし // El t2 t l t2 // どこかで 与

パイプラインとFIFOイプラインとFIFOデ デデ デデデータラッチ

演算器

データラッチ

データラッ

演算器

データラッ

演算器

データラッ

演算器

チ チチ チチ

デー

デー

デー

デー

デーー

タラッチ

ータラッチ

ータラッチ

ータラッチ

ータラッチチ チチ チチ

※演算器がなければFIFOハードウェアによる実装

Page 13: アルゴリズムとデータ構造1...new_element1->next = next_element1; // リストのデータ構造// Java言語でアクセッサなし // El t2 t l t2 // どこかで 与

値型と参照型ふたたび値型と参照型ふたたび…

• 現代の主流はノイマン型プロセッサによる計算– 命令はメモリに蓄積し、逐次読み出し実行– データもメモリに置き 命令に従って処理されるみなさんは今、データ構造を勉強し、プログラムを勉強しています。– デ タもメモリに置き、命令に従って処理される

• メモリからのロード・ストア、四則演算、論理演算

機械語のレベルではデ タはほぼすべて参照型

今、 構 勉強 、 勉強 すそれでは、プログラムが動作中のメモリのイメージはわかりますか?Javaにおける基本型とオブジェクト(構造型)を説明できますか?そして値型と参照型に いて説明できますか• 機械語のレベルではデータはほぼすべて参照型

– データどおしの代入という操作すらないものが多いそして値型と参照型について説明できますか?

– アドレスを指定してロード、アドレスを指定してストア• つまりデータはアドレスにより参照されるつまりデ タはアドレスにより参照される

– このあたりの区別がわかりやすいので実験2ではH8を使う– 身近なIA32アーキテクチャとそのアセンブラはわかりにくい

Page 14: アルゴリズムとデータ構造1...new_element1->next = next_element1; // リストのデータ構造// Java言語でアクセッサなし // El t2 t l t2 // どこかで 与

// リストのデータ構造// Java言語でアクセッサありpublic class Element1{

/* リストのデータ構造 *//* C言語版その1 */union Object {

i t I t{public Element1(Object aData){

this.data = aData;

int Integer;double Double;

};struct Element1 {;

}public Object getData(){

tu n this d t ;

{union Object data;struct Element1 *next;

};return this.data;

}public Element1 getNextElement(){

// リストのデータ構造// Java言語でアクセッサなしpublic class Element2{

return this.next;}public void setNextElement(Element1 anNextElement){

{public Element2(){}{

this.next = anNextElement;}private Object data; // 参照型

}public Object data;public Element2 next;

}p jprivate Element1 next;

}/* リストのデータ構造 *//* C言語版その2 */struct Element2 {

id *d tvoid *data;struct Element2 *next;

};

Page 15: アルゴリズムとデータ構造1...new_element1->next = next_element1; // リストのデータ構造// Java言語でアクセッサなし // El t2 t l t2 // どこかで 与

// リストのデータ構造 // Java言語でアクセッサあり// Element1 next_element1; // どこかで与えられている

Element1 new_element1; 100

new_element1 = new Element1(new Integer(100));new_element1. setNextElement(next_element1);

/* リストのデータ構造 *//* C言語版その1 */Integerのインスタンス

1/* struct Element1 *next_element1: /* どこかで与えられている */struct Element1 *new_element1;

new_element1 = malloc(sizeof (struct Element1));

Element1のインスタンス

getData()

100new_element1datanextnew_element1->data.Integer = 100;

new_element1->next = next_element1;// リストのデータ構造 // Java言語でアクセッサなし// El t2 t l t2 // どこかで与えられている

getNextElement()setNextElement()

data

datanext

next element1100

next

// Element2 next_element2; // どこかで与えられているElement2 new_element2;

new_element2 = new Element2();l t2 d t I t (100)

next

Element1のインスタンスnext element1

next_element1

next

100

/* リストのデータ構造 *//* C言語版その2 *//* struct Element2 *next element2: /* どこかで与えられている */

new_element2.data = new Integer(100);new_element2. next = next_element2;

Element2のインスタンス

getData()getNextElement()setNextElement()

next_element1

new_element2

next

next_element1data

/ struct Element2 next_element2: / どこかで与えられている /struct Element2 *new_element2;

new_element2 = malloc(sizeof (struct Element2));new element2->data = malloc(sizeof (int));

Element2のインスタンス

datanext

()datanextElement2のインスタンスnext

new_element2->data = malloc(sizeof (int));*((int *)new_element2->data) = 100; /* cast as lvalue で行儀が悪い */new_element2->next = next_element2;

next_element2

datanext

Page 16: アルゴリズムとデータ構造1...new_element1->next = next_element1; // リストのデータ構造// Java言語でアクセッサなし // El t2 t l t2 // どこかで 与

// リストのデータ構造// Java言語でアクセッサありpublic class Element1{

/* リストのデータ構造 *//* C言語版その1 */struct Element1 {

i t d t{public Element1(int aData){

this.data = aData;

int data;struct Element1 *next;

};

// デ タ構造;

}public int getData(){

tu n this d t ;

// リストのデータ構造// Java言語でアクセッサなしpublic class Element2{return this.data;

}public Element1 getNextElement(){

{public Element2(){}

bli i d{

return this.next;}public void setNextElement(Element1 anNextElement){

public int data;public Element2 next;

}/* リストのデ タ構造 */{

this.next = anNextElement;}private int data; // 値型

/* リストのデータ構造 *//* C言語版その2 */struct Element2 {

int *data;pprivate Element1 next;

}struct Element2 *next;

};

Page 17: アルゴリズムとデータ構造1...new_element1->next = next_element1; // リストのデータ構造// Java言語でアクセッサなし // El t2 t l t2 // どこかで 与

// リストのデータ構造 // Java言語でアクセッサあり// Element1 next_element1; // どこかで与えられている

Element1 new_element1; 100

new_element1 = new Element1(100);new_element1. setNextElement(next_element1);

/* リストのデータ構造 *//* C言語版その1 *//* struct Element1 *next_element1: /* どこかで与えられている */

struct Element1 *new_element1;

new_element1 = malloc(sizeof (struct Element1));

new_element1 Element1のインスタンス

getData()datanextnew_element1->data.Integer = 100;

new_element1->next = next_element1;// リストのデータ構造 // Java言語でアクセッサなし// El t2 t l t2 // どこかで与えられている

datanext

getNextElement()setNextElement()

100

next

// Element2 next_element2; // どこかで与えられているElement2 new_element2;

new_element2 = new Element2();l t2 d t 100

Element1のインスタンスnext element1

next

next100

/* リストのデータ構造 *//* C言語版その2 *//* struct Element2 *next element2: /* どこかで与えられている */

new_element2.data = 100;new_element2. next = next_element2;

Element2のインスタンス

getData()getNextElement()setNextElement()

next_element1

new_element2

next

nextdata

/ struct Element2 next_element2: / どこかで与えられている /struct Element2 *new_element2;

new_element2 = malloc(sizeof (struct Element2));new element2->data = malloc(sizeof (int));

Element2のインスタンス

100

next

()datanextElement2のインスタンス

new_element2->data = malloc(sizeof (int));*((int *)new_element2->data) = 100; /* cast as lvalue で行儀が悪い */new_element2->next = next_element2;

next_element2

datanext

Page 18: アルゴリズムとデータ構造1...new_element1->next = next_element1; // リストのデータ構造// Java言語でアクセッサなし // El t2 t l t2 // どこかで 与

まとめまとめ• データ構造

– 配列・リスト・スタック・待ち行列・木• プログラムへの変換プ グラム の変換

– 参照型と値型の違い・利害得失メモリのイメ ジ• メモリのイメージ– 抽象的なデータ構造との対応

• プログラミング言語による違いJavaにもポインタは存在する– Javaにもポインタは存在する• ただし、ポインタ演算はない。

J と異なり 構造型は値型 ある– Javaと異なり、Cの構造型は値型である• Javaのほうが参照を多用するけど、表立って見えない