プログラミングI第10回

Similar documents
Taro-リストⅠ(公開版).jtd

Taro-リストⅢ(公開版).jtd

バイオプログラミング第 1 榊原康文 佐藤健吾 慶應義塾大学理工学部生命情報学科

PowerPoint Template

PowerPoint プレゼンテーション

Taro-ポインタ変数Ⅰ(公開版).j

memo

PowerPoint プレゼンテーション

memo

Microsoft PowerPoint - exp2-02_intro.ppt [互換モード]

Microsoft Word - 第5回 基本データ構造2(連結リスト).doc

memo

Microsoft PowerPoint - 05.pptx

Microsoft PowerPoint - kougi9.ppt

Taro-スタック(公開版).jtd

7 ポインタ (P.61) ポインタを使うと, メモリ上のデータを直接操作することができる. 例えばデータの変更 やコピーなどが簡単にできる. また処理が高速になる. 7.1 ポインタの概念 変数を次のように宣言すると, int num; メモリにその領域が確保される. 仮にその開始のアドレスを 1

プログラミング方法論 II 第 14,15 回 ( 担当 : 鈴木伸夫 ) 問題 17. x 座標と y 座標をメンバに持つ構造体 Point を作成せよ 但し座標 は double 型とする typedef struct{ (a) x; (b) y; } Point; 問題 18. 問題 17 の

Microsoft Word - no206.docx

Taro-2分探索木Ⅰ(公開版).jtd

memo

演算増幅器

プログラミングI第5回

PowerPoint プレゼンテーション

Microsoft PowerPoint - lec10.ppt

memo

PowerPoint プレゼンテーション

Microsoft Word - Cプログラミング演習(12)

Microsoft Word - no205.docx

Microsoft PowerPoint - 6.pptx

(2) 構造体変数の宣言 文法は次のとおり. struct 構造体タグ名構造体変数名 ; (1) と (2) は同時に行える. struct 構造体タグ名 { データ型変数 1; データ型変数 2;... 構造体変数名 ; 例 : struct STUDENT{ stdata; int id; do

始めに, 最下位共通先祖を求めるための関数 LcaDFS( int v ) の処理を記述する. この関数は値を返さない再帰的な void 関数で, 点 v を根とする木 T の部分木を深さ優先探索する. 整数の引数 v は, 木 T の点を示す点番号で, 配列 NodeSpace[ ] へのカーソル

Taro-2分探索木Ⅱ(公開版).jtd

第2回

Microsoft Word - no15.docx

Microsoft PowerPoint - kougi10.ppt

Microsoft Word - Cプログラミング演習(11)

問 2 ( 型変換 ) 次のプログラムを実行しても正しい結果が得られない 何が間違いかを指摘し 正しく修正せよ ただし int サイズが 2 バイト long サイズが 4 バイトの処理系での演算を仮定する #include <stdio.h> int main( void ) { int a =

第1回 プログラミング演習3 センサーアプリケーション

Prog1_10th

プログラミングI第6回

Microsoft Word - 3new.doc

第3回 配列とリスト

1. 入力した正の整数を降順に並べ換えて出力するプログラムを作成せよ プログラムは個別にコンパイルし make コマンドで実行すること 入力データは 50 以下とし 以下の数が混在しているとする 16 進数 : 先頭 1 文字が x または X( エックスの小文字か大文字 ) 8 進数 : 先頭 1

RX ファミリ用 C/C++ コンパイラ V.1.00 Release 02 ご使用上のお願い RX ファミリ用 C/C++ コンパイラの使用上の注意事項 4 件を連絡します #pragma option 使用時の 1 または 2 バイトの整数型の関数戻り値に関する注意事項 (RXC#012) 共用

プログラミング基礎

C プログラミング演習 1( 再 ) 2 講義では C プログラミングの基本を学び 演習では やや実践的なプログラミングを通して学ぶ

Microsoft PowerPoint - 11.pptx

Microsoft Word - 13

Microsoft PowerPoint - H22プログラミング第一(E)#12

O(N) ( ) log 2 N

02: 変数と標準入出力

第2回

Microsoft Word - no12.doc

Microsoft PowerPoint - CproNt02.ppt [互換モード]

02: 変数と標準入出力

概要 プログラミング論 構造体 構造体 複数の変数を組合わせて, ひとまとめにしたもの 簡単 重要 自己参照型, リスト 重要, 難しい S-1 S-2 新しい構造体の宣言 struct 構造体名 { データ型メ

プログラミング実習I

gengo1-11

コマンドラインから受け取った文字列の大文字と小文字を変換するプログラムを作成せよ 入力は 1 バイトの表示文字とし アルファベット文字以外は変換しない 1. #include <stdio.h> 2. #include <ctype.h> /*troupper,islower,isupper,tol

Microsoft PowerPoint - 06.pptx

PowerPoint Presentation

program7app.ppt

kiso2-09.key

Microsoft PowerPoint Java基本技術PrintOut.ppt [互換モード]

講習No.9

Microsoft Word - Cプログラミング演習(7)

演習課題No12

Microsoft PowerPoint - prog03.ppt

Prog1_15th

02: 変数と標準入出力

情報処理Ⅰ演習

Microsoft PowerPoint - 12.ppt [互換モード]

Microsoft Word - Cプログラミング演習(10)

Microsoft PowerPoint pptx

Microsoft Word - Training10_プリプロセッサ.docx

PowerPoint プレゼンテーション

02: 変数と標準入出力

次に示す数値の並びを昇順にソートするものとする このソートでは配列の末尾側から操作を行っていく まず 末尾の数値 9 と 8 に着目する 昇順にソートするので この値を交換すると以下の数値の並びになる 次に末尾側から 2 番目と 3 番目の 1

Microsoft PowerPoint - kougi11.ppt

Microsoft PowerPoint - handout07.ppt [互換モード]

第 3 回 Java 講座 今回の内容 今週の Java 講座はコレクション 拡張 for 文, ガベージコレクションについて扱う. 今週の Java 講座は一番内容が薄いも のになるだろう. コレクション コレクションとは大きさが決まっていない配列だと考えればよい. コレクションには List 先

Microsoft PowerPoint - 13.ppt [互換モード]

02: 変数と標準入出力

プログラミングI第11回

02: 変数と標準入出力

r07.dvi

< F2D837C E95CF CF68A4A94C5816A2E6A>

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

ohp07.dvi

JavaプログラミングⅠ

第3回 配列とリスト

untitled

Microsoft PowerPoint pptx

プログラミング及び演習 第1回 講義概容・実行制御

講習No.12

alg2015-3r3.ppt

Microsoft PowerPoint - 計算機言語 第7回.ppt

memo

今回のプログラミングの課題 ( 前回の課題で取り上げた )data.txt の要素をソートして sorted.txt というファイルに書出す ソート (sort) とは : 数の場合 小さいものから大きなもの ( 昇順 ) もしくは 大きなものから小さなもの ( 降順 ) になるよう 並び替えること

Transcription:

プログラミング 1 第 10 回 構造体 (3) 応用 リスト操作 この資料にあるサンプルプログラムは /home/course/prog1/public_html/2007/hw/lec/sources/ 下に置いてありますから 各自自分のディレクトリにコピーして コンパイル 実行してみてください Prog1 2007 Lec 101 Programming1 Group 19992007

データ構造 : リスト データが 一連 のメモリに保管される 最も簡単なデータ構造は配列である リニアサーチ は配列を検索するための方法だった 1072004 調べたい学生番号 1072001 1072004 1072050 データ 64 93 59 検索して得た情報 もっと効率的なデータ構造として 連結リスト (linked list) がある Prog1 2007 Lec 102 Programming1 Group 19992007

連結リスト (list) リスト はデータ構造の一種 何らかのしかけで一方向又は双方向に順に繋がる ( 連結 ) 矢印で繋がった各データを ノード ( 節 ) 又はセル と呼ぶ リストを矢印の方向にたどることが出来る 連結リストの実現 ( 実装 ) 方法は様々である ここでは 教科書 6.1とはちょっと違う実装を試みる この授業では一方向のものだけを説明する 双方向につながる 双方向リスト もあるので興味の有る人は調べてみると良い Prog1 2007 Lec 103 Programming1 Group 19992007

ノード 各ノードは構造体 ( タグ node) で実現されており 以下の要素を持つ データを保管する領域 : この例においては int 型変数 key 次のノードを示す領域 :node 型構造体ポインタ next KEY NEXT KEY NEXT struct node { int key; struct node *next; ; typedef struct node * NodePointer; 簡単のため Node 型ポインタを NodePointer と typedef する 構造体の宣言の中に自分自身の構造体へのポインタを持つものを 自己参照的構造体 と言う データを保管する領域には key 以外に他のデータも入れることができる Prog1 2007 Lec 104 Programming1 Group 19992007

リストの特徴 リストは配列とは異なり 各ノードがメモリの中で順に並んでいる必要はないし sizeof(struct node) のアドレスだけ離れている必要もない 大量のメモリ空間を一括に確保できなくても容易に利用できるし 必要に応じて長さを動的に変更することも簡単である 配列より少し複雑になるが メモリをより効率的に利用できる特徴がある Prog1 2007 Lec 105 Programming1 Group 19992007

ノードの連結 次のノードへのリンク ( 矢印 ) の実現 (x y の順で繋げるとする ) ノード x y のアドレスがそれぞれ 1200 番地 1100 番地だとする ノード x の next ( つまり x>next) に次のノード ( つまり y) のアドレス ( つまり 1100) というアドレスを入れる これで x y と言う連結が出来た事になる リストをたどるには順に next のアドレスをたどれば良い x(1200) KEY NEXT=1100 y(1100) KEY NEXT x>next = &y &y Prog1 2007 Lec 106 Programming1 Group 19992007

リストの構造 head NULL ノード 便宜的に先頭 (head) ノードを連結リストに付加する 先頭 (head) はリスト先頭にあり 前のノードがない headではkeyは使わないので不定とする headは外部変数として定義されてる ( 複数のリストを扱うときは不便 ) リストの終端 ( 最後のノード ) はヌルポインタ (NULL) となっている 初期状態はhead のみが存在し nextはヌルポインタとなっている ( 下図 ) リスト構造の実現方法は様々なバリエーションがある head KEY NEXT NULL Prog1 2007 Lec 107 Programming1 Group 19992007

新しいノードを作る : ノードへのメモリの割り当て 連結リストでは通常必要な分だけノードを作成する このような方法を 実行の途中にメモリを割り当てることから 動的リストと呼ぶ 以下がノード作成の関数である ノード1 個分のメモリ割り当てでは 割り当てるバイト数は sizeof(struct node) である NodePointer make_1node(int keydata, NodePointer p){ NodePointer n; if((n = malloc(sizeof(struct node))) == NULL) { printf("error in memory allocation\n"); exit(8); 何らかの理由でmalloc が失敗したら終了する n>key = keydata; n>next = p; keyとnextに引数の値をセットする return n; n KEY NEXT Prog1 2007 Lec 108 Programming1 Group 19992007

リストの初期化 head KEY NEXT NULL リストの初期化は簡単である 行うことは以下の 2 つで 関数 make_1node を呼ぶだけである head ノードの作成 next を NULL( ヌルポインタ ) にする NodePointer head; head; head は main の外で定義つまり外部 ( グローバル ) 変数 head head = make_1node(0,null); head ノードを作成する値は仮に 0 とする ( 何でも良い ) next に NULL( ヌルポインタ ) を設定する Prog1 2007 Lec 109 Programming1 Group 19992007

リストの表示 Head 2 5 7 NULL 1 回目 n 2 回目 n 3 回目 n 終了 head から NULL の前まで key の値を出力 void listprint(void){ NodePointer n; head の次からスタート 例の場合の出力 : Head 2 5 7 printf("head"); for(n = head>next; n!= NULL; n = n>next){ printf(" %d", n>key); リストを順にたどる printf("\n"); NULLになるまでノードを一つずつ表示する Prog1 2007 Lec 1010 Programming1 Group 19992007

検索方法 23 23を検索 発見! 終了 15 23 42 NULL 1 つ前のポインタを返す key が keydata( 例では 23) のノード n を検索する手順 : 1 値 keydata を head の次から NULL の前まで順に key と比較する 2 発見したら一つ前のノードへのポインタを返す 3 発見出来なかったら NULL を返す 一つ前のポインタを返す理由 : 削除の時に便利 ( 後述 ) Prog1 2007 Lec 1011 Programming1 Group 19992007

検索ソース NodePointer finditem(int keydata) { NodePointer n; next が NULL になるまで探す 1 for(n = head; n>next!= NULL; n = n>next){ if(n>next>key == keydata) return n; return NULL; 次のノードの key と keydata を比較する 1 見つかったら一つ前のノード (n) をリターン 2 発見出来なかったら NULL をリターン 3 keydata を head の次から NULL の前まで順に key と比較し 発見したら一つ前のノードへのポインタを返す ; 発見出来なかったら NULL を返す Prog1 2007 Lec 1012 Programming1 Group 19992007

検索イメージ head NULL 最初 n n>next ループ 2 回目 n n>next ループ 3 回目 n n>next ループ 4 回目 終了 n n>next Prog1 2007 Lec 1013 Programming1 Group 19992007

リストの構築 ( 挿入 ) 方法 head 4 3 NULL 2 newnode head の直後に key が keydata の値のノード newnode を挿入する手順 : 1 keyがkeydataのノードを検索する もしあればNULLをリターンし 終了 もしなければ ( 検索結果がNULLなら ) 以下の処理を行う 2 keyがkeydataのノード newnode を作成 3 newnode>next を head>next と同じ ( 代入 ) にする 4 head>next を newnode にする Prog1 2007 Lec 1014 Programming1 Group 19992007

挿入ソース headの直後にkeyがkeydataのノードnewnode を挿入する NodePointer insert(int keydata) { NodePointer newnode; key が keydata のノードを検索し なければ新しいノードを作り リストに挿入する ; あれば NULL を返す 1 if(finditem(keydata) == NULL){ newnode = make_1node(keydata,head>next); head>next = newnode; return newnode; else return NULL; head>next を newnode にする 4 key が keydata のノード newnode を作成 2 newnode>next を head>next と同じ ( 代入 ) にする 3 Prog1 2007 Lec 1015 Programming1 Group 19992007

プログラム (1) /* struct declaration */ struct node { int key; struct node *next; ; typedef struct node * NodePointer; ヘッダファイル list.h /* prototype declaration */ NodePointer insert(int); NodePointer finditem(int); void listprint(void); NodePointer make_1node(int,nodepointer); /* Global Variable head */ NodePointer head; プログラム全体はプログラム全体は /home/course/prog1/public_html/2007/lec/source/{lec101.c,list.h にあるにある Prog1 2007 Lec 1016 Programming1 Group 19992007

プログラム (2) #include <stdio.h> #include <stdlib.h> #include "list.h" main(){ int i,num; printf("[initial]\n"); head = make_1node(0,null); for (i = 1; i <= 9 ; ++i) insert(i); listprint(); printf("[insert](enter number)\n"); while(scanf("%d",&num) == 1){ if (insert(num) == NULL) printf("data %d is already on the list\n",num); listprint(); Prog1 2007 Lec 1017 Programming1 Group 19992007

NodePointer insert(int keydata){ NodePointer newnode; プログラム (3) if(finditem(keydata) == NULL){ newnode = make_1node(keydata,head>next); head>next = newnode; return newnode; else return NULL; /* in case of data found */ void listprint(void){ NodePointer n; printf("head"); for(n = head>next; n!= NULL; n = n>next) { printf(" %d", n>key); printf("\n"); Prog1 2007 Lec 1018 Programming1 Group 19992007

NodePointer finditem(int keydata){ NodePointer n; プログラム (4) for(n = head; n>next!= NULL; n = n>next){ if(n>next>key == keydata) return n; return NULL; /* in case of not found */ NodePointer make_1node(int keydata, NodePointer p){ NodePointer n; if((n = malloc(sizeof(struct node))) == NULL) { printf("error in memory allocation\n"); exit(8); n>key = keydata; n>next = p; return n; Prog1 2007 Lec 1019 Programming1 Group 19992007

実行結果 s1000000{std0ss0:1 s1000000{std0ss0:1./a.out./a.out [Initial] [Initial] Head Head 9 9 8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 [Insert](enter [Insert](enter number) number) 55 Data Data 5 5 is is already already on on the the list list Head Head 9 9 8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 10 10 Head Head 10 10 9 9 8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 25 25 Head Head 25 25 10 10 9 9 8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 Control+D Control+D s1000000{std0ss0:2 s1000000{std0ss0:2 Prog1 2007 Lec 1020 Programming1 Group 19992007