1 ななちゃんの IT 教室教養講座 : データ構造の巻 第 1 回秘密道具 : マイ コンソール なな : クリじい データ構造 の勉強をするんだけど 便利な秘密道具はない? クリ : あるぞ あるぞ 定番秘密道具の マイ コンソール 他の巻を読んでない読者のために 説明しよう 1 ここに Jav

Similar documents
ななちゃんの IT 教室 メニューを極めようの巻 by ななちゃんが メニューの使い方をマスターするというお話 第 0.1 版 2017 年 6 月 23 日 フリー素材 いらすとやフリー素材 h

ななちゃんの IT 教室 データ構造 : 複素数の巻 by ななちゃんが 複素数データ構造を使ってみるというお話 第 0.1 版 2017 年 7 月 3 日 フリー素材 いらすとやフリー素材 h

1 ななちゃんの IT 教室デバッグ奥義の巻 第 1 回デバッグとは なな : これって 朝日新聞の ののちゃんの DO 科学 のパクリ? 先生 : パロディって言ってちょうだい 家政婦のミタ ( 家政婦は見た のパロディ ) クレヨンしんちゃんのダズニーラ ンド ( ディズニーランド のパロディ

Microsoft PowerPoint - 05.pptx

memo

Microsoft PowerPoint - 06.pptx

Microsoft PowerPoint - kougi10.ppt

Microsoft PowerPoint - algo ppt [互換モード]

ななちゃんの IT 教室 関数について詳しくなろうの巻 by ななちゃんが JavaScript の関数の使い方を詳しく学ぶというお話 第 0.1 版 2017 年 6 月 18 日 フリー素材

alg2015-6r3.ppt

PowerPoint Presentation

第2回

Microsoft PowerPoint _2b-DOM.pptx

第2回

Microsoft Word - no06.doc

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

Microsoft Word - NonGenTree.doc

memo

人工知能入門

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

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

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

PowerPoint Presentation

Microsoft PowerPoint - algo ppt [互換モード]

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

JavaScript 1.! DOM Ajax Shelley Powers,, JavaScript David Flanagan, JavaScript 2

memo

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

離散数学

Microsoft PowerPoint - 6.pptx

Microsoft Word - NonGenList.doc

Microsoft Word - no12.doc

プログラム言語及び演習Ⅲ

Java Scriptプログラミング入門 3.6~ 茨城大学工学部情報工学科 08T4018Y 小幡智裕

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

Microsoft Word - no206.docx

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

CプログラミングI

JavaScriptで プログラミング

Taro-最大値探索法の開発(公開版

PowerPoint Presentation

1. はじめに 二分木ヒープ 様々なアルゴリズムにおいて ある要素の集合またはリストから 最小 な要素を取り 出す必要がある そのような場合に使われる標準的データ構造が二分木ヒープ (binary heap) である あるオブジェクトO を考える そのオブジェクトは ラベル O. label と値

2. データ構造ヒープに保存するデータは 番号付けられて保存される 従って リスト L として保存することとする 3. アルゴリズム 3.1. 要素の追加新しい要素の追加は リストの終端に置くことで開始する つまり 最下層の一番右 または新たに最下層を生成してその一番左となる この後 この要素を正し

PowerPoint Template

alg2015-3r3.ppt

プログラミング入門1

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

Microsoft Word - 中間試験 その1_解答例.doc

プログラミングI第10回

第7回 Javascript入門

NetworkApplication-09

前ページからの続き // テキストボックス02 id 属性で取得 // id 属性で取得する場合は一意に決まるので 何番目かの指定は不要 var textbox02elem = document.getelementbyid("text_box02_id"); if ("001" == statee

Taro-再帰関数Ⅲ(公開版).jtd

Microsoft PowerPoint - lec10.ppt

基礎計算機演習 実習課題No6

1 ななちゃんの IT 教室データ構造 : 行列の巻 第 1 回秘密道具 : マイ コンソール なな : クリじい データ構造 の勉強をするんだけど 便利な秘密道具はない? クリ : あるぞ あるぞ 定番秘密道具の マイ コンソール 他の巻を読んでない読者のために 説明しよう 1 ここに JavaS

JavaScript 演習 2 1

memo

文字列操作と正規表現

Microsoft PowerPoint - kougi11.ppt

情報処理Ⅰ

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

PG13-6S

E4X in Firefox nanto_vi (TOYAMA Nao)

PowerPoint Presentation

PowerPoint プレゼンテーション

第12回 モナドパーサ

alg2015-4r2.ppt

JavaScriptプログラミング入門 2.JavaScriptの概要

メソッドのまとめ

PowerPoint プレゼンテーション

第 8 回の内容 クライアントサイド処理 JavaScript の基礎

Si 知識情報処理

Taro-cshプログラミングの応用.jt

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

大容量情報検索論

intra-mart Accel Platform — IM-Repository拡張プログラミングガイド   初版  

3,, となって欲しいのだが 実際の出力結果を確認すると両方の配列とも 10, 2, 3,, となってしまっている この結果は代入後の配列 a と b は同じものになっていることを示している つまり 代入演算子 = によるの代入は全要素のコピーではなく 先をコピーする ため 代入後の a と b は

デジタル表現論・第4回

Microsoft PowerPoint - Pro110111

Microsoft Word _VBAProg1.docx

データ構造

演習室の PC のハードディスクには演習で作成したデータは保管できません 各 PC の ネットワーク接続 ショートカットからメディア情報センターのサーバーにアクセスしてください (Z ドライブとして使用できます ) 演習名 使用するフォルダ 演習 1 Z: Web データ管理 演習

memo

PowerPoint プレゼンテーション

プレポスト【解説】

Web データ管理 JavaScript (1) (4 章 ) 2011/12/7( 水 ) 湘南工科大学講義資料 Web データ管理 (2011) 阿倍 1/21

Microsoft Word - 13

Microsoft PowerPoint - ruby_instruction.ppt


ポインタ変数

Webデザイン論

PowerPoint プレゼンテーション

プログラミング入門1

JavaScript演習

模擬試験問題(第1章~第3章)

ななちゃんの IT 教室 マルチタートルでオブジェクトを理解しようの巻 by 複数のタートルを操作する環境でななちゃんがオブジェクト指向とは何かを勉強します 第 0.7 版 2017 年 5 月 7 日 フリー素材

( ) ( ) 30 ( ) 27 [1] p LIFO(last in first out, ) (push) (pup) 1

LIFO(last in first out, ) 1 FIFO(first in first out, ) 2 2 PUSH POP : 1

Transcription:

ななちゃんの IT 教室 教養講座 : データ構造の巻 by nara.yasuhiro@gmail.com ななちゃんが データ構造の基礎 ( リスト 二分木 ) を学ぶというお話 第 0.1 版 2017 年 6 月 21 日 フリー素材 http://freeillustration.net いらすとやフリー素材 http://www.irasutoya.com/ もくじ第 1 回秘密道具 : マイ コンソール第 2 回データ構造とは第 3 回リスト構造第 4 回検索 ソーティング第 5 回スタックとキュー第 6 回二分木第 7 回ヒープソート

1 ななちゃんの IT 教室教養講座 : データ構造の巻 第 1 回秘密道具 : マイ コンソール なな : クリじい データ構造 の勉強をするんだけど 便利な秘密道具はない? クリ : あるぞ あるぞ 定番秘密道具の マイ コンソール 他の巻を読んでない読者のために 説明しよう 1 ここに JavaScript の命令を書きこむ 複数行でも良い 2 実行ボタンをクリック 3 実行した結果の 値 が表示される 出力例 JavaScript の命令 log() で 出力することもできる <= 1 + 2; => Number number 3 <= "1" + "2" => String string "12" <= 1;2; => Number number 2 <= var x = 1; => Undefined undefined undefined <= x => Number number 1 <= var x; x= 1; => Number number 1 1 + 2; // Number number 3 "1" + "2" // String string "12" 1;2; // Number number 2 var x = 1; // Undefined undefined undefined x // Number number 1 var x; x= 1; // Number number 1 JavaScript 命令 実行結果の 型 と 値 <= 1 + 2; => Number number 3 注意 :var x = 1; の値は undefined 本教材ではこのように圧縮表示しています JavaScript 命令 1+2 を入力した 実行結果の 値 は 3 実行結果の 型 は Number 型 の判定方法は 2 種類 r 〇 ; 〇 のように 複数の JavaScript 命令がある場合 一番右の命令の型 値だけ表示される

ななちゃんの IT 教室教養講座 : データ構造の巻 2 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> コンソール </title> </head> <body> <h3> コンソール </h3> <textarea rows="19" cols="80" id=pg autofocus>1 + 2;</textarea> <br><input type=button onclick=go() value=" 実行 "> <br> システムからのメッセージ <br><textarea rows="20" cols="80" id=log></textarea> <script> var geval = eval; var logp = document.getelementbyid("log"); var pgp = document.getelementbyid("pg"); var logd; function clog(s) { logp.value += s; function log(s) { logd += s; function typeis(obj) { return(object.prototype.tostring.call(obj).slice(8, -1)); function isprimitive(x) { return (typeof x)!="object"; function toliteral(x) { if (typeis(x)=="number" && isnan(x)) return "NaN"; if (x === Infinity) return "Infinity"; if ((typeis(x)!="symbol")&&(-x === Infinity)) return "-Infinity"; if (typeis(x)=="set") return "Set("+JSON.stringify([...x])+")"; if (typeis(x)=="map") return "Map("+JSON.stringify([...x])+")"; return JSON.stringify(x); function type(x) { return "" + (typeof x); function isinteger(n) { return n%1 === 0; function keys(obj) { return Object.keys(obj); function go() { logd = ""; try { var v = geval(pgp.value); clog("<= " + pgp.value + "\n=> " + typeis(v) + " " + type(v) + " " + toliteral(v) + "\n"); pgp.value = ""; logp.scrolltop = logp.scrollheight; pgp.focus(); catch(e) { clog("<= " + pgp.value + "\n=>! " + e + "\n"); pgp.value = ""; logp.scrolltop = logp.scrollheight; pgp.focus(); if (logd!= "") clog(logd + "\n"); </script> </body> </html>

3 ななちゃんの IT 教室教養講座 : データ構造の巻 なな : データ構造って何? 第 2 回データ構造とは 先生 : JavaScript の基本機能でいえば 文字列とか 配列とか オブジェクトのようなもの たとえば 文字列の場合 一文字ずつ分解して 配列データにしたり オブジェクトにすることもできるわけね どういう処理を どういうアルゴリズムで実現するのかと データ構造としてどれを選ぶかということが密接に関係しているの たとえば 各文字を書き換えることが必要なら 文字列より配列が良いとか 挿入や削除が多かったらオブジェクトのほうが良いかも知れません プログラムのトータル性能は アルゴリズムとデータ構造の組み合わせで決まってくるということです なな : 文字列とか 配列とか オブジェクトのどれを使うか選択するということ? 先生 : JavaScript 組み込みのデータ構造を使う以外にも オブジェクトを使って 独自のデータ構造を作ることもできます なな : たとえば どういうの? 先生 : 今回の巻では リスト構造 二分木 ヒープ それから リスト構造を使ったスタックとキューを紹介しましょう スタックとキューは 配列を使っても実現できるので そういう意味では 上位のデータ構造というか より抽象度の高いデータ構造と言えるかも知れません 組み合わせるアルゴリズムは ソーティングや検索をとりあげます なな : どれが良いというか 高級なの? 先生 : アルゴリズムとの組み合わせによります 挿入削除が頻繁に必要なアルゴリズムなのかとか データは順番 にアクセスすることが多いのか インデックスを使って とびとびにアクセスする必要があるかとか

ななちゃんの IT 教室教養講座 : データ構造の巻 4 なな : リスト構造って何? 第 3 回リスト構造 先生 : データをバラバラにして 順にポインタで連結したデータ構造です 連結リスト (Linked list) とも呼ばれます ポインタを書き換えるだけで データの 挿入や削除が行えるのが特徴です 配列だと データを挿入 削除した場合 それより後ろのデータをすべて移動する必要があるので 時間がかかりますが リスト構造では移動が不要です リスト構造では データアクセスには 先頭から順に探索してゆきます 配列のように いきなり 50 番目のデータにアクセス というようなことはできません 1 2 3 / 1 2 3 / 0 1 2 3 / function LNode(first, second) { this.f = first; this.s = second; LNode.prototype.disp = function d() { if (this.f === null) return ""; if (this.s === null) return this.f + ""; return this.f + "," + d.call(this.s); ; LNode.prototype.dp = function d() { return "<" + this.disp() + ">"; ; LNode.prototype.insert = function (first) { if (this.f === null) { this.f = first; this.s = null; return this; var temp = this.s; this.s = new LNode(this.f,this.s); this.f = first; return this; ; LNode.prototype.advance = function () { if (this.s === null) return new LNode(null,null); return this.s; ; LNode.prototype.delete = function () { if (this.s === null) { this.f = null; return this; this.f = this.s.f; this.s = this.s.s; return this; ; LNode.prototype.append = function (first) { if (this.f === null) { this.f = first; this.s = null; return this; this.s = new LNode(first,this.s); return this.s; ; 1 つのデータ ( ノード ) のコンストラクタ f (first) がデータ部分 s (second) がポインタ部分 注目点を 追加ノードに移動 リスト構造全体を表示するメソッド データを一つ 注目ノードの前に追加するメソッド 注目ノードを一つ先に移動するメソッド データを一つ削除するメソッド データを一つ 注目ノードの後に追加するメソッド

5 ななちゃんの IT 教室教養講座 : データ構造の巻 第 4 回検索 ソーティング 先生 : リストを利用したソーティングプログラムです 先頭からデータを見てゆき 新データより大きいデータを発見し たら その手前に挿入します 空のリストからはじめ ひとつずつデータを挿入してゆくことで 昇順にならんだ リストが構築されます LNode.prototype.step = function self(d) { var save = this; 場所をみつけて新データを挿入 if (this.f === null) this.f = d; else if (this.f > d) this.insert(d); else if (this.s === null) this.append(d); else self.call(this.advance(),d); return save; 末尾到達 新データを追加再帰呼び出し ; var node = new LNode(null,null); node.dp(); // String string "<>" node.step(1).step(2).step(5).step(3).dp(); // String string "<1,2,3,5>" [3,8,6,5,4,9,2,7,1].reduce(function(prev,cur) { return prev.step(cur);, new LNode(null,null)).dp(); // String string "<1,2,3,4,5,6,7,8,9>" 先生 : すでに作られている 昇順にデータが並んでいるリストデータの中から 特定のデータを検索し みつかったら 削除するプログラムです var node = new LNode(null,null); node.append(1).append(2).append(3).append(4).append(5); node.dp(); // String string "<1,2,3,4,5>" function remove(d) { var n = node; while (true) { if (n.f == d) n.delete(); if (n.s === null) break; n = n.advance(); remove(3); node.disp(); // String string "<1,2,4,5>" データがみつかったら削除 動作確認 <1,2,3,4,5> から 3 を削除

ななちゃんの IT 教室教養講座 : データ構造の巻 6 第 5 回スタックとキュー 先生 : リストを使って スタックと キューを作ってみました まず スタック FILO (First In Last Out) ともいいま す なな : リストを使って スタックが作れるの? 先生 : プッシュは insert ポップは advance や delete で実現できます それぞれの例です A B C の順に プッシュしてからポップすると C B A の順にデータが得られます たとえば <B,A> の状態のスタックで stack.f で 先頭のデータを取りだすことができます var stack = new LNode(null,null); stack.insert("a").insert("b").insert("c").dp(); // String string "<C,B,A>" (stack = stack.advance()).dp(); // String string "<B,A>" (stack = stack.advance()).dp(); // String string "<A>" (stack = stack.advance()).dp(); // String string "<>" var stack = new LNode(null,null); stack.insert("a").insert("b").insert("c").dp(); // String string "<C,B,A>" stack.delete().dp(); // String string "<B,A>" stack.delete().dp(); // String string "<A>" stack.delete().dp(); // String string "<>" 先生 : これは キューの例です キューは FIFO (First In First Out) とも呼ばれます 配列を使うと 大量データの移動が必要になってしまいます リストを使えば データ移動は不要です この例では A B C の順に入力し A B C の順に取り出しています var fifo = new LNode(null,null); fifo.append("a").append("b").append("c"); fifo.dp(); // String string "<A,B,C>" fifo.delete().dp(); // String string "<B,C>" fifo.delete().dp(); // String string "<C>" fifo.delete().dp(); // String string "<>" なな : 順番が変わらないんだったら 何に使うの? 先生 : データが不規則なタイミングで発生する場合 それを等間隔に取り出せたり コンピュータが処理できしだい ただちに次のデータを取り出せるよう データを先行的にキューにためておいたりできます また コンピュータ で処理したデータをキューにためておき あとでゆっくりディスクに書き込むなどという用途に使えます なな : バッファとか キャッシュとかいうものね

7 ななちゃんの IT 教室教養講座 : データ構造の巻 第 6 回二分木 なな : 二分木って何? 先生 : 下図のような形のデータ構造を二分木 (binary tree) といいます それぞれの節 ( )( ノード ) は 最大 2つの枝を持ち その枝先には さらに節を持ちます 枝を持たない節を 葉 ともいいいます 例 : データ 3,8,6,5,4,9,2,7,1 を順に二分木に格納する 1. まず 3 をルートに格納する ( 図 1) 2. 8 は 3 より大きいので その右側の節に格納する ( 図 2) 3. 6 は 3 より大きいので右へ 次の 8 より小さいので その左側に格納する ( 図 3) 4. 5 は 3 より大きいので右へ 次の 8 より小さいので左へ 次の 6 より小さいのでその左に格納 ( 図 4) 5. 4 は 3 より大きいので右へ 次の 8 より小さいので左へ 次の 6 より小さいので左へ 次の 5 より小さいので その左に格納 ( 図 5) 6. 9 は 3 より大きいので右へ 次の 8 より大きいので その右側に格納する ( 図 6) 7. 2 は 3 より小さいので その左側に格納する ( 図 7) 8. 7 は 3 より大きいので右へ 次の 8 より小さいので左へ 次の 6 より大きいので その右に格納 ( 図 8) 9. 1 は 3 より小さいので左へ 次の 2 より小さいので その左側に格納する ( 図 9) 上の例のように格納したデータ 3,8,6,5,4,9,2,7,1 を小さい順 ( 昇順 ) に整列します それぞれの節に枝があるときは 左側の方が小さいので 葉に到達するまで 左の枝をたどってゆきます 例の場合 まず 1 が得られます 1 の節には枝がないので 2 に戻ります 2 の節には右の枝がないのでさらに戻ります 次に 3 の節の右の枝をたどってゆきます このように ルートから左の枝をたどって下へ降りてゆきます 葉まで到達したら上へ戻ってゆきます 戻ったときに右の枝があればその枝をたどって下に降ります これを繰り返しデータを取得することで昇順に整列することができます リスト構造と大きくことなる点は データを先頭から連続して見るのでなく とびとびに見られることです

ななちゃんの IT 教室教養講座 : データ構造の巻 8 function btree(key,left,right) { this.k = key; this.l = left; this.r = right; 二分木ノードのコンストラクタ btree.prototype.disp = function self() { 二分木の整列表示 if (this.k === null) return ""; return self.call(this.l) + " " + this.k + " " + self.call(this.r); btree.prototype.addbt = function self(n) { if (this.k === null) { this.k = n; this.l = new btree(null,null,null); this.r = new btree(null,null,null); else if (this.k < n) this.r = self.call(this.r,n); else this.l = self.call(this.l,n); return this; 新しいデータを二分木に格納する (new btree(null,null,null)).addbt(3).addbt(8).addbt(6).addbt(5).addbt(4).addbt(9).addbt(2).addbt(7).addbt(1).disp(); // String string " 1 2 3 4 5 6 7 8 9 " [3,8,6,5,4,9,2,7,1].reduce(function(prev,cur) { return prev.addbt(cur);, new btree(null,null,null)).disp(); // String string " 1 2 3 4 5 6 7 8 9 " ECMAScript 2015 の reduce を使う場合二分木に格納する

9 ななちゃんの IT 教室教養講座 : データ構造の巻 なな : ヒープって何? 第 7 回ヒープソート 先生 : ヒープ (heap) は 累積 積み重なったもの という意味です データ構造としては 親の値が子供の 値以上であるような完全 2 分木です 2 分探索木と異なり 左のノードが右のノードより小さいとは限りま せん ヒープの各ノードに 上 下 左 右に A1 A2 と 番号をつけると Ai の親は Ai/2 i/2 は 整数割り算 切捨て Ai の左の子は,Ai*2 Ai の右の子は,Ai*2+1 という関係になります これを 番号順に配列要素に対応させることができます 末尾から先頭に向かって 親と子のデータを順に比較 子のほうが大きかったら 親とデータを交換 上端のデータが最大になるので それを取り出す 末尾のデータを上端に移し 末尾を削除 以上の処理を データがひとつになるまで繰り返します var x = [1,12,3,4,15,6,10,8,9,7,11,2,13,14,5]; var i, j, tmp, s = "" for (i = x.length; i >= 1; i--) { for (j = Math.floor(i/2); j >= 1; j--) { if (x[j-1] < x[j*2-1]) { tmp = x[j-1]; x[j-1] = x[j*2-1]; x[j*2-1] = tmp; if (((j*2+1) <= i) && (x[j-1] < x[j*2])) { tmp = x[j-1]; x[j-1] = x[j*2]; x[j*2] = tmp; s += x[0] + " "; x[0] = x[i-1]; s; // String string "15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 "