アルゴリズムとデータ構造1...new_element1->next = next_element1; //...
TRANSCRIPT
アルゴリズムとデータ構造アルゴリズムとデータ構造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
待ち行列(FIFO)(44ページ)待ち行列(FIFO)(44ペ ジ)
データ挿入 データ取得デ タ挿入 デ タ取得
待ち行列(データの挿入・取得)
待ち行列の配列による実現待ち行列の配列による実現
データ挿入 データ取得デ タ挿入 デ タ取得
新しい要素を入れようとすると入らない→右へコピーして移動→隙間を空ける→隙間を空ける
リングバッファ(46ページ)リングバッファ(46ペ ジ)
配列の最初と最後を接続して環にしたもの
のポインタでデ タの出し入れを管理2つのポインタでデータの出し入れを管理
データの先頭を指すポインタ
head, frontデータの最後尾を指すポインタデ タの最後尾を指すポインタ
tail, rear2つのポインタが重なったらデータは空2つのポインタが重なったらデータは空
領域の大きさをnとしたらポインタの位置はnとおりデ タの数が0から まで 1とおりあるデータの数が0からnまでn+1とおりあるポインタが重なったら、空か満杯の状態が重なる…
リングバッファリア
挿入口リア
•環状のデータ格納領域デ タ 存在を すポ タ•データの存在を示すポインタ
取り出し口
フロント
満杯になったとき、リアとフロントのポインタが
重なってしまって
フロントリア リア
重なってしまって空と区別が付かない
配列を使用したリングバッファ配列を使用したリングバッファ
配列には始まりと終わりがある配列には始まりと終わりがある
ポインタが終わりまで移動したら先頭へ戻る
(フロント-リア)の演算でも境界を考慮
ラップラウンド処理ラップラウンド処理
ラップラウンド処理ラップラウンド処理
条件文で判定
配列の大きさを2のべき乗にする配列のインデックスをビットごとのAND処理
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;
}}
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);
}}
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);}
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();
}
パイプラインとFIFOイプラインとFIFOデ デデ デデデータラッチ
演算器
データラッチ
データラッ
演算器
データラッ
演算器
データラッ
演算器
チ チチ チチ
デー
デー
デー
デー
デーー
タラッチ
ータラッチ
ータラッチ
ータラッチ
ータラッチチ チチ チチ
※演算器がなければFIFOハードウェアによる実装
値型と参照型ふたたび値型と参照型ふたたび…
• 現代の主流はノイマン型プロセッサによる計算– 命令はメモリに蓄積し、逐次読み出し実行– データもメモリに置き 命令に従って処理されるみなさんは今、データ構造を勉強し、プログラムを勉強しています。– デ タもメモリに置き、命令に従って処理される
• メモリからのロード・ストア、四則演算、論理演算
機械語のレベルではデ タはほぼすべて参照型
今、 構 勉強 、 勉強 すそれでは、プログラムが動作中のメモリのイメージはわかりますか?Javaにおける基本型とオブジェクト(構造型)を説明できますか?そして値型と参照型に いて説明できますか• 機械語のレベルではデータはほぼすべて参照型
– データどおしの代入という操作すらないものが多いそして値型と参照型について説明できますか?
– アドレスを指定してロード、アドレスを指定してストア• つまりデータはアドレスにより参照されるつまりデ タはアドレスにより参照される
– このあたりの区別がわかりやすいので実験2ではH8を使う– 身近なIA32アーキテクチャとそのアセンブラはわかりにくい
// リストのデータ構造// 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;
};
// リストのデータ構造 // 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
// リストのデータ構造// 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;
};
// リストのデータ構造 // 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
まとめまとめ• データ構造
– 配列・リスト・スタック・待ち行列・木• プログラムへの変換プ グラム の変換
– 参照型と値型の違い・利害得失メモリのイメ ジ• メモリのイメージ– 抽象的なデータ構造との対応
• プログラミング言語による違いJavaにもポインタは存在する– Javaにもポインタは存在する• ただし、ポインタ演算はない。
J と異なり 構造型は値型 ある– Javaと異なり、Cの構造型は値型である• Javaのほうが参照を多用するけど、表立って見えない