1 / 98

コンピュータ基礎演習  ー探索、整列ー

コンピュータ基礎演習  ー探索、整列ー. 岩井 儀雄 iwai@sys.es.osaka-u.ac.jp. 線形探索と二分探索. 線形探索法 (linear search) データを最初から順番に探索する 例) {2, 4, 5, 8, 9, 11, 6, 7, 15, 20} から 15 を探す  最初の要素から始めて9回目→計算量 O(n) 二分探索法 (binary search) データをあらかじめソートしておき,中央の要素から検索する.. 二分探索 (binary search).

Télécharger la présentation

コンピュータ基礎演習  ー探索、整列ー

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. コンピュータ基礎演習 ー探索、整列ー 岩井 儀雄 iwai@sys.es.osaka-u.ac.jp

  2. 線形探索と二分探索 • 線形探索法(linear search) • データを最初から順番に探索する 例){2, 4, 5, 8, 9, 11, 6, 7, 15, 20} から15を探す  最初の要素から始めて9回目→計算量O(n) • 二分探索法(binary search) • データをあらかじめソートしておき,中央の要素から検索する.

  3. 二分探索(binary search) • {2, 4, 5, 6, 7, 8, 9, 11, 15, 20} から15を探す 1回目 {2, 4, 5, 6, 7, 8, 9, 11, 15, 20}

  4. 二分探索(binary search) • {2, 4, 5, 6, 7, 8, 9, 11, 15, 20} から15を探す 2回目 {2, 4, 5, 6, 7, 8, 9, 11, 15, 20}

  5. 二分探索(binary search) • {2, 4, 5, 6, 7, 8, 9, 11, 15, 20} から15を探す 3回目 {2, 4, 5, 6, 7, 8, 9, 11, 15, 20} 探索回数 3回 計算量  log2(n) O(log n)

  6. 整列(sort) • 内部整列(internal sort) • 主記憶上で行う整列 • 外部整列(external sort) • 外部記憶装置(テープ等)上で行う 整列アルゴリズムの優劣→比較回数と交換回数の大小

  7. 安定な整列(stable sort) • 同じ値を持つデータ間の順序関係が整列の前後で保たれている 例)整列前: 7 9 5A 4 8 5B 2   整列後: 2 4 5A 5B 7 8 9 (安定)   整列後: 2 4 5B 5A 7 8 9 (不安定)

  8. 単純な整列(バブルソート) • 配列の後ろから先頭に向かって走査し,もし隣り合う二つの要素の大小関係が逆であったら入れ替える 整列前 20 6 55 74 3 45 13 87 46 30 1回目 比較

  9. 単純な整列(バブルソート) • 配列の後ろから先頭に向かって走査し,もし隣り合う二つの要素の大小関係が逆であったら入れ替える 1回目 20 6 55 74 3 45 13 87 30 46 入替

  10. 単純な整列(バブルソート) • 配列の後ろから先頭に向かって走査し,もし隣り合う二つの要素の大小関係が逆であったら入れ替える 1回目 20 6 55 74 3 45 13 87 30 46 比較

  11. 単純な整列(バブルソート) • 配列の後ろから先頭に向かって走査し,もし隣り合う二つの要素の大小関係が逆であったら入れ替える 1回目 20 6 55 74 3 45 13 30 87 46 入替

  12. 単純な整列(バブルソート) • 配列の後ろから先頭に向かって走査し,もし隣り合う二つの要素の大小関係が逆であったら入れ替える 1回目 20 6 55 74 3 45 13 30 87 46 比較

  13. 単純な整列(バブルソート) • 配列の後ろから先頭に向かって走査し,もし隣り合う二つの要素の大小関係が逆であったら入れ替える 1回目 20 6 55 74 3 45 13 30 87 46 比較

  14. 単純な整列(バブルソート) • 配列の後ろから先頭に向かって走査し,もし隣り合う二つの要素の大小関係が逆であったら入れ替える 1回目 20 6 55 74 3 13 45 30 87 46 入替

  15. 単純な整列(バブルソート) • 配列の後ろから先頭に向かって走査し,もし隣り合う二つの要素の大小関係が逆であったら入れ替える 1回目 20 6 55 74 3 13 45 30 87 46 比較

  16. 単純な整列(バブルソート) • 配列の後ろから先頭に向かって走査し,もし隣り合う二つの要素の大小関係が逆であったら入れ替える 1回目 20 6 55 74 3 13 45 30 87 46 20 6 55 3 74 13 45 30 87 46 20 6 3 55 74 13 45 30 87 46 20 3 6 55 74 13 45 30 87 46 3 20 6 55 74 13 45 30 87 46

  17. 単純な整列(バブルソート) • 配列の後ろから先頭に向かって走査し,もし隣り合う二つの要素の大小関係が逆であったら入れ替える 2回目 3 20 6 55 74 13 45 30 87 46 46 87 30 46 30 45 13 30 13 74 13 55 6 13 6 20

  18. 単純な整列(バブルソート) • 配列の後ろから先頭に向かって走査し,もし隣り合う二つの要素の大小関係が逆であったら入れ替える 2回目 36 20 13 55 74 30 45 46 87 3回目 3 6 13 20 30 55 74 45 46 87 4回目 3 6 13 20 30 45 55 74 46 87 5回目 3 6 13 20 30 45 46 55 74 87 6回目 3 6 13 20 30 45 46 55 74 87 7回目 3 6 13 20 30 45 46 55 74 87 8回目 3 6 13 20 30 45 46 55 74 87 9回目 3 6 13 20 30 45 46 5574 87

  19. バブルソート(疑似コード) for (i←0..n-1) for (j←n-1..i) if !(a[j-1] ≦ a[j]) swap(a[j-1],a[j]) 右辺値の交換 整列アルゴリズムが満たす事後条件 計算量は O(n2)

  20. バブルソート(C言語) for (i←0..n-1) for (j←n-1..i) if !(a[j-1] ≦ a[j]) swap(a[j-1],a[j]) void bubble_sort(int a[],int n) { int I,j,t; for (int I=0; I<n-1; ++I) for (int j=n-1; j>I; --j) if (a[j-1] > a[j]) { t = a[j]; a[j] = a[j-1]; a[j-1] = t; } } swap(a[j-1],a[j])に相当する

  21. 単純な整列(選択ソート) • 未整列部分から最小の要素を選び出し,それを未整列部分の先頭と入れ替える 未整列部分 整列済 未整列部分から最小値を取り出し 続けると下記の条件を満たす 整列アルゴリズムが満たす事後条件

  22. 選択ソート 整列前 20 6 55 74 3 45 13 87 46 30 1回目 入替

  23. 選択ソート 整列前 20 6 55 74 3 45 13 87 46 30 1回目 3 6 55 74 20 45 13 87 46 30

  24. 選択ソート 整列前 20 6 55 74 3 45 13 87 46 30 1回目 3 6 55 74 20 45 13 87 46 30 2回目 3 6 55 74 20 45 13 87 46 30 入替

  25. 選択ソート 整列前 20 6 55 74 3 45 13 87 46 30 1回目 3 6 55 74 20 45 13 87 46 30 2回目 3 6 55 74 20 45 13 87 46 30 3回目  3 613 74 20 45 55 87 46 30 4回目  3 613 20 74 45 55 87 46 30 5回目  3 613 2030 45 55 87 46 74 6回目  3 613 2030 45 55 87 46 74 7回目  3 613 2030 45 46 87 55 74 8回目  3 613 2030 45 46 55 87 74 9回目  3 613 2030 45 46 55 74 87

  26. 選択ソート(疑似コード) for (i←0..n-2) lowest←argmin(a[j]) i<j<n swap(a[i],a[lowest])

  27. 選択ソート(C言語) void selection_sort(int a[],int n) { int i,j,t,lowest,lowval; for (i = 0; i<n-1; ++i) { lowest = i; lowval = a[i]; for (j = i+1; j < n; ++j) if (a[j] < lowval) { lowval = a[j]; lowest = j; } t = a[I]; a[I] = a[lowest]; a[lowest] = t; } } argminの計算部分

  28. 選択ソートの計算量 • ループ n 回,argmin の計算量 O(n) • 選択ソートの計算量は O(n2)

  29. 単純な整列(挿入ソート) • 配列の一部分が整列済みの時に,残りの要素を一つずつ整列済みの中に挿入する 整列前 20 6 55 74 3 45 13 87 46 30 1回目  6 20 55 74 3 45 13 87 46 30 2回目 6 2055 74 3 45 13 87 46 30 3回目  6 205574 3 45 13 87 46 30 4回目  3 6 20 55 74 45 13 87 46 30 5回目  3 6 20 45 55 74 13 87 46 30 6回目  3 6 13 20 45 55 74 87 46 30 7回目  3 6 13 20 45 55 74 87 46 30 8回目  3 6 13 20 45 46 55 74 87 30 9回目  3 6 13 20 30 45 46 55 74 87

  30. 挿入ソート(疑似コード) for (i←0..n-1) j←i while (! (a[j-1] ≦ a[j]) ) swap( a[j-1], a[j] ) j←j-1 計算量:外側ループ O(n) 内側ループ O(n) 合計: O(n2)

  31. コンピュータ基礎演習 ー計算量ー 岩井 儀雄 iwai@sys.es.osaka-u.ac.jp

  32. 計算量(complexity) • 時間計算量(time complexity) • アルゴリズムがデータに対してどれくらい時間がかかるかを示す • 空間計算量(space complexity) • アルゴリズムがデータに対してどれくらい記憶領域を必要とするかを示す • 時間計算量と空間計算量はトレードオフの関係にあることが多い • 計算機にとって記憶資源は潤沢にあるので,通常時間計算量の方が重きを置かれることが多い

  33. オーダー記法O • 計算量T(n)の上界値を評価するとき,O(f(n))という記法を用い,オーダーf(n) と読む. ある正定数cとn0が存在して,n0以上のnに対して, 常に T(n) ≦cf(n) が成立するという意味 n0の役割は有限個の例外を許すことにある.

  34. オーダー記法Ω • 計算量の下界値のオーダーを表すには,記法Ωを用いる.T(n)=Ω(f(n))とは,

  35. 計算量とオーダ表記の関係 計算量の上界O 計算量 実際の計算量 有限個の 例外はOK 計算量の下界Ω n n0

  36. オーダーの演算 例)

  37. 最悪計算量と平均計算量 • 同じアルゴリズムでも入力するデータに応じて計算量が変化する.そこで,客観的に測定し評価する必要がある. • 最悪計算量 worst case complexity • 全ての入力パターンに対して最大の計算量を要するものに基づいて定める • 平均計算量 average complexity • 全ての入力パターンとその入力の生起確率に基づいて計算量の平均を求める

  38. コンピュータ基礎演習 ー再帰ー 岩井 儀雄 iwai@sys.es.osaka-u.ac.jp

  39. 再帰 • 再帰的(recursive)な構造とは,自分自身(n次)を定義するのに,自分自身より1次低い集合(n-1次)を用い,さらにその部分集合は,より低次の部分集合を用いて定義するということを繰り返す構造.このような構造を一般的に再帰(recursion)と呼ぶ.

  40. 再帰 • 数学ではいろいろな概念を再帰的に定義している. 例)数列

  41. 再帰呼び出し • 関数の中で自分自身を関数として呼び出すこと 例)数列 int A(int n) { if (n == 1) return 1; /* 再帰呼び出しの停止条件 */ else return A(n-1)+2*n-1; }

  42. 再帰呼び出し例 • 階乗(n!)の計算プログラム #include <stdio.h> int factorial(int n) { if (n == 0) return 1; else return n*factorial(n-1); } int main() { int n; for (n=0; n<10; ++n) printf( “ %2d! = %d\n”, n, factorial(n) ); return 0; }

  43. 階乗(n!)の計算実行例 10! = 3628800 11! = 39916800 12! = 479001600 13! = 1932053504 14! = 1278945280 15! = 2004310016 16! = 2004189184 17! = -288522240 18! = -898433024 19! = 109641728 0! = 1 1! = 1 2! = 2 3! = 6 4! = 24 5! = 120 6! = 720 7! = 5040 8! = 40320 9! = 362880 演算結果が正しくない 13! = 6227020800 14! = 87178291200 15! = 1307674368000 16! = 20922789888000 17! = 3555687428096000 18! = 64023737057280000 19! = ? 実行:PowerBook G4, MacOS X 10.2.5, gcc 3.1 intが32ビットなら,正の数は 231 = 2147483648までしか表現できない

  44. 演習課題 • フィボナッチ数列を再帰を用いて求める #include <stdio.h> int fibonacci(int n) { if (n == 1 || n == 2) return 1; else return fibonacci(n-1)+fibonacci(n-2); } int main() { int n; for (n=0; n<20; ++n) printf( “ %2d! = %d\n”, n, fibonacci(n) ); return 0; }

  45. コンピュータ基礎演習 ーリスト構造ー 岩井 儀雄 iwai@sys.es.osaka-u.ac.jp

  46. ADT Stack (スタック) • データの集まり • 一番上の要素しか操作できない • イメージ的には物を上に積んだ状態 スタックに可能な操作 ・一番上の要素の値を見る(top) ・一番上の要素を取り除く(pop) ・上に要素を積む(push) ・スタックが空?(isEmpty) ・スタックの要素数(size)

  47. ADT Queue(待ち行列) • データの集まり • 要素の挿入,削除が端でしかできない • イメージ的には人の待ち行列 待ち行列の先頭

  48. ADT Stack, ADT Queue の実装 • 前回は配列を使って実装した • 今回はリスト構造を使って実装する • →まずはリスト構造について

  49. リスト構造 • 連結リスト • 循環リスト • 双方向リスト

  50. 連結リスト(Linked list) • データの集まり • データが一覧表(リスト)のように連なっている構造 • 連なりの表現には効率のため,ポインタが用いられることが多い • もちろん,配列とインデックスでも実装できる(リスト容量が制限)

More Related