第10回 ソート(1):単純なソートアルゴリズム

Slides:



Advertisements
Similar presentations
アルゴリズムと データ構造 第 3 回 基本的なデータ構造(2) : 配列 1. 前回の復習 アルゴリズムの計算量 最悪(最大)計算量 計算量の漸近的評価 (オーダ)  多項式時間アルゴリズム( polynomial time algorithm )  指数時間アルゴリズム( exponential.
Advertisements

逐次ソート 2011/05/16. ソート(sort) 順序集合の要素a 1 … a n の上下関係を整 える 一般的には、整数の集合 N を考えればよ い ソートの計算量が問題となる どのような入力に対し、どのようなアル ゴリズムが最適か?
データ構造とアルゴリズム 平成20年度 前期 2年生必修  水曜日 3-4時限.
「コンピュータやネットワーク等の活用事例」
離散システム特論 整列(sorting)アルゴリズム 2.
データ構造とアルゴリズム論 第5章 整列(ソート)のアルゴリズム
ヒープソートの演習 第13回.
アルゴリズムイントロダクション第2章 主にソートに関して
4.ソート 4-1.ソート問題について 4-2.簡単なソートアルゴリズム 4-3.高度なソートアルゴリズム
アルゴリズムとデータ構造 2012年6月27日
第12回 ソート(3): シェルソート、クイックソート
アルゴリズムとデータ構造 第8回 ソート(3).
第10回 整列 ~ バブルソート,挿入ソート,選択ソート~
第11回 整列 ~ シェルソート,クイックソート ~
データ構造とアルゴリズム論 第5章 整列(ソート)のアルゴリズム
情報基礎演習B 後半第5回 担当 岩村 TA 谷本君.
第11回 整列 ~ バケットソート,基数ソート,ヒープソート~
2009/10/30 整列アルゴリズム (2) 第5講: 平成21年10月30日 (金) 4限 E252教室 コンピュータアルゴリズム.
第7講: 平成19年11月2日 (金) 4限 E252教室 クイックソートと オーダー記法.
データ構造とアルゴリズム論 第6章 探索のアルゴリズム
2009/10/9 良いアルゴリズムとは 第2講: 平成21年10月9日 (金) 4限 E252教室 コンピュータアルゴリズム.
4.整列のアルゴリズム.
情報処理Ⅱ 2005年12月9日(金).
データ構造とアルゴリズム 分割統治 ~ マージソート~.
配列の扱い、探索 有効範囲と記憶域期間 第12回 [7月10日、H.15(‘03)] 今日のメニュー 1 前回の課題の復習
岩井 儀雄 コンピュータ基礎演習  ー探索、整列ー 岩井 儀雄
ヒープソートの復習.
データ構造と アルゴリズム 第八回 知能情報学部 新田直也.
アルゴリズム入門.
第11回 整列 ~ シェルソート,クイックソート ~
第3回 配列,構造体,ポインタ ~ データ構造について学ぶための基礎~
プログラミング基礎a 第8回 プログラムの設計 アルゴリズムとデータ構造
2009/11/6 整列アルゴリズムの復習 第6講: 平成21年11月6日 (金) 4限 E252教室 コンピュータアルゴリズム.
アルゴリズムとデータ構造1 2006年6月16日
アルゴリズムとデータ構造1 2005年7月15日
ソートアルゴリズムの種類 選択ソート (selection sort) バブルソート (bubble sort)
情報工学概論 (アルゴリズムとデータ構造)
講義では、Cプログラミングの基本を学び 演習では、やや実践的なプログラミングを通して学ぶ
わんくま同盟茶藝部顧問 Microsoft MVP for VC episthmh
データ構造とアルゴリズム論 第6章 整列(ソート)のアルゴリズム
マイクロソフト Access での SQL 演習 第4回 並べ替え(ソート)
茨城大学 工学部 知能システム工学科 井上 康介 E2棟801号室
クイックソート.
P n ポインタの基礎 5 q m 5 7 int* p; int 型の変数を指すポインタ int* q; int 型の変数を指すポインタ int n=5, m=7; int 型の変数 int array[3]; int* pArray[3]; p = &n; ポインタにアドレスを代入しているのでOK.
アルゴリズムとプログラミング (Algorithms and Programming)
先進的計算基盤システムシンポジウム SACSIS2007併設企画 マルチコアプログラミングコンテスト 「Cellスピードチャレンジ2007」
復習その1+α JBuilderの使い方を思い出す。 配列とGUI
プログラミング基礎a 第8回 プログラムの設計 アルゴリズムとデータ構造
データ構造とアルゴリズム論 第5章 整列(ソート)のアルゴリズム
データ構造とアルゴリズム論 第5章 整列(ソート)のアルゴリズム
プログラミング 4 整列アルゴリズム.
2009/10/23 整列アルゴリズム (1) 第4講: 平成21年10月23日 (金) 4限 E252教室 コンピュータアルゴリズム.
プログラミング 4 探索と計算量.
データ構造とアルゴリズム論 第5章 整列(ソート)のアルゴリズム
プログラミング 4 木構造とヒープ.
アルゴリズムとデータ構造1 2006年7月11日
アルゴリズムとデータ構造 2011年6月23日
プログラミング演習Ⅲ- Sorting Quick Sort and Merge Sort
アルゴリズムとデータ構造 --- 理論編 --- 山本 真基
データ構造とアルゴリズム (第5回) 静岡大学工学部 安藤和敏
アルゴリズムとプログラミング (Algorithms and Programming)
バブルソート,バケツソート,クイックソート
ヒープソートの復習 第12回.
ソートのプログラムの流れ 配列の中身を小さい順に並び替える a[1],a[2],…a[n]の値を順に出力する
アルゴリズムとデータ構造 2012年6月25日
プログラミング基礎演習 第4回.
参考:大きい要素の処理.
情報処理Ⅱ 小テスト 2005年2月1日(火).
プログラミング論 バイナリーサーチ 1.
ファーストイヤー・セミナーⅡ 第10回 if文による選択処理(2).
Presentation transcript:

第10回 ソート(1):単純なソートアルゴリズム アルゴリズムと データ構造 第10回 ソート(1):単純なソートアルゴリズム

先週の復習 再帰の基本 再帰関数呼び出し 再帰呼出しを使うことのメリット 再帰的アルゴリズムの作り方 再帰呼出しの時間計算量 再帰関数の応用例 ハノイの塔 8王妃問題

先週の演習問題

答え: 解説 recur(-1) : (何も実行されない) recur(0) : (何も実行されない) recur(1) : → 1 recur(2) : recur(0) 2 recur(1) → 2 21 1 recur(3) : recur(1) 3 recur(2) → 1321 1 3 21 recur(4) : recur(2) 4 recur(3) → 2141321 21 4 1321 recur(5) : recur(3) 5 recur(4) → 1321 132152141321 5 2141321 recur(6) : → recur(4) 6 recur(5) 2141321 21413216132152141321 6 132152141321 答え:

ソート(整列、ソーティング、sorting)   本日の内容 単純なソートアルゴリズム バブルソート 挿入ソート 選択ソート 比較によらないソート バケットソート 基数ソート シェルソート クイックソート マージソート

ソートの基本 レコードの集まりを,キーの値の大小関係に従って昇順(または降順)に並べかえる操作 ソートの対象は,複数の欄からなるレコード 身長をキーとして 降順にソート 氏名と身長欄から成るレコード. Cでは,構造体を用いて記述 青木 177 小田 158 金子 170 佐藤 174 渡辺 青木 177 佐藤 174 金子 170 渡辺 小田 158 同じキーをもつレコードが 複数ある時は連続して並ぶ

昇順、降順 昇順(ascending order) 降順(descending order) 数値の場合、小さいものから大きいものへ 1,3,5,8,10 文字列の場合、辞書式順序 a, aa, abc, g, zz, zzzz 降順(descending order) 数値の場合、大きいものから小さいものへ 10,8,5,3,1 文字列の場合、辞書式順序の逆 zzzz, zz, g, abc, aa, a

ソートアルゴリズムの要件 計算量 (時間的,空間的) 内部ソート / 外部ソート 安定 / 不安定 計算量 (時間的,空間的) 内部ソート / 外部ソート ランダムアクセス可能なメモリの利用を前提とする方式か否か 安定 / 不安定 キーの値が同じデータを整列した場合に整列前の位置関係が維持されるか 10, 3, 5, 3, 1 ⇒ 1, 3, 3, 5, 10 安定 10, 3, 5, 3, 1 ⇒ 1, 3, 3, 5, 10 不安定

内部ソートと外部ソート 主記憶 (メモリ) ランダム 外部記憶 (磁気テープなど) シーケンシャル 主記憶 (メモリ) ランダム 外部記憶 整列したい データ 2 5 1 6 7 整列したい データ 2 5 1 6 7 10 40 3 4 35 1 2 5 6 7 2 5 1 6 7 主記憶にコピー 入りきらない

安定なソート   同じキーをもつレコードが2つ以上ある場合に,整列前の位置関係が整列後も保たれているアルゴリズムを安定である(stable)という 5A 7 4 8 5B 3 2  安定なアルゴリズムによる整列結果 不安定なアルゴリズムによる整列結果 2 3 4 5A 5B 7 8  2 3 4 5B 5A 7 8 

ソート(整列)アルゴリズムの分類 バブルソート O(n2) 挿入ソート 選択ソート バケットソート O(n) 基数ソート O(mn) ソート(整列)アルゴリズムの分類  名称 計算量 内部/外部 安定/不安定 備考 バブルソート O(n2) 内部 安定 挿入ソート 選択ソート 不安定 バケットソート O(n) データに制限有 基数ソート O(mn) シェルソート O(n1.25)~ O(n1.5) クイックソート O(n log n)  最悪O(n2) マージソート O(n log n) 外部

O(n2)とO(n log n)の比較 n が大きいとき,O(n2)とO(n log n)の差は顕著 例) n = 32 = 25のとき n log2 n = 32×log2 25 = 32×5 = 160 n = 1024 = 210のとき n2 = 220 = 1048576 ≒ 100万 n log2 n = 1024×log2 210 = 1024×10 = 10240 ≒ 1万 6.4倍 100倍

バブルソート(bubble sort) 7 別名:単純交換ソート a [0] 7 別名:単純交換ソート 配列の後ろから先頭に向かってスキャンし,隣り合う2つの要素の大小関係が逆であったら入れかえる [1] 3 [2] 5 [3] 9 [4] 6 [5] 4 8 2 8 9 2 9 [n-1] 2

バブルソートのコード a i → [0] 整数を昇順に並べる場合 [1] void bubble_sort(int a[], int n) { int i, j; for (i = 0; i < n - 1; i++){ for (j = n - 1; j > i; j--){ if(a[j] < a[j-1]) a[j]とa[j-1]を交換; } [1] [2] [3] [4] [5] j → [n-1]

バブルソートの実行例1 a[0] a[1] a[6] 1 6 1 6 4 1 6 4 3 4 1 3 7 7 1 3 1 7 1 9 8 9 9 8 8

バブルソートの実行例2 a[0] a[1] a[8] 整列前 9 3 2 1 4 7 5 5 8 i=0のあと i=1のあと 整列前  9 3 2 1 4 7 5 5 8 i=0のあと i=1のあと i=2のあと 1 2 3 9 4 5 5 7 8 i=3のあと 1 2 3 4 9 5 5 7 8 i=4のあと 1 2 3 4 5 9 5 7 8 i=5のあと 1 2 3 4 5 5 9 7 8 i=6のあと 1 2 3 4 5 5 7 9 8 i=7のあと 1 2 3 4 5 5 7 8 9 整列済 ←

バブルソートの実行例2 a[0] a[1] a[8] 整列前 9 3 2 1 4 7 5 5 8 バブルソートの実行例2  a[0] a[1] a[8] 整列前  9 3 2 1 4 7 5 5 8 i=0のあと 1 9 3 2 4 5 7 5 8 i=1のあと 1 2 9 3 4 5 5 7 8 i=2のあと 1 2 3 9 4 5 5 7 8 i=3のあと 1 2 3 4 9 5 5 7 8 i=4のあと 1 2 3 4 5 9 5 7 8 i=5のあと 1 2 3 4 5 5 9 7 8 i=6のあと 1 2 3 4 5 5 7 9 8 i=7のあと 1 2 3 4 5 5 7 8 9 整列済 ←

バブルソートの実行例2 a[0] a[1] a[8] 整列前 9 3 2 1 4 7 5 5 8 整列前  9 3 2 1 4 7 5 5 8 i=0のあと 1 9 3 2 4 5 7 5 8 i=1のあと 1 2 9 3 4 5 5 7 8 i=2のあと 1 2 3 9 4 5 5 7 8 i=3のあと 1 2 3 4 9 5 5 7 8 i=4のあと 1 2 3 4 5 9 5 7 8 i=5のあと 1 2 3 4 5 5 9 7 8 i=6のあと 1 2 3 4 5 5 7 9 8 i=7のあと 1 2 3 4 5 5 7 8 9 整列済 ← 安定なソート

問題1 次のデータをバブルソートで昇順に並べ替える経過を示しなさい。 a[5] = {9,3,4,1,4};

i j a[0] a[1] a[2] a[3] a[4] 初期状態 9 3 4 1 4 3 2 1

i j a[0] a[1] a[2] a[3] a[4] 初期状態 9 3 4 1 4 4 4 1 3 9 4 1 3 9 3 4 3 1 9 2 4 3 9 1 1 4 3 9 1 4 1 4 3 9 1 3 1 4 9 3 1 2 1 4 9 3 1 4 2 4 9 3 1 3 2 9 4 3 1 4 3

バブルソートの計算量 全体 O(n2) 比較: ⇒ O(n2) i のループ n-1回 i=0 i=1 i=n-2 a [0] [1] [2] [3] j: n-1回 j: n-2回 j: 1回 全体 O(n2) [n-1] 比較: ⇒ O(n2) 交換:(a[j]<a[j-1])の個数: 逆順の場合、比較の回数分交換も起こる ⇒ O(n2)

挿入ソート(insertion sort) i番目の要素を0〜iの間の適切な位置に挿入する ソート済 a [0] [1] [i-1] [i] [n-1] 3 5 8 10 11 7 実行例 1 6 4 3 4 4 1 1 7 7 3 3 9 9 8 8 8

j >= 1を満たさないのでwhileループを抜ける 挿入ソートのコード a[0] 3 2 void insertion_sort(int a[], int n) { int i, j; for (i = 1;i < n; i++){ j = i; while (j >= 1 && a[j] < a[j-1]){ a[j]とa[j-1]を交換; j--; } j → i → [1] 3 2 [2] 1 [3] 4 [4] [n-1]

j >= 1を満たさないのでwhileループを抜ける 挿入ソートのコード a[0] 1 2 2 1 3 void insertion_sort(int a[], int n) { int i, j; for (i = 1;i < n; i++){ j = i; while (j >= 1 && a[j] < a[j-1]){ a[j]とa[j-1]を交換; j--; } j → [1] 2 i → [2] 3 [3] 4 [4] [n-1]

jは i ~ 1までの全てについて繰りかえし調べるのではなく,適切な挿入位置で止まる 挿入ソートのコード  a[0] 2 3 2 1 3 1 2 3 void insertion_sort(int a[], int n) { int i, j; for (i = 1;i < n; i++){ j = i; while (j >= 1 && a[j] < a[j-1]){ a[j]とa[j-1]を交換; j--; } [1] 2 [2] 1 [3] j → i → 4 [4] jは i ~ 1までの全てについて繰りかえし調べるのではなく,適切な挿入位置で止まる [n-1]

番兵(Sentinel) 配列の範囲を超えないよう見張るために使用 決してa[j]とa[j-1]の交換が起きないような値を入れておくことで,コードを簡略化できる i ↓ a [0] [1] [i-1] [i] [n-1] [n] -∞ 3 5 8 10 1 ← j 番兵

挿入ソートのコード2 -∞ 3 2 3 2 1 4 a [0] j → [1] 番兵を使う場合 void insertion_sort(int a[], int n) { int i, j; a[0] = -∞; for (i = 2;i <= n; i++){ j = i; while (a[j] < a[j-1]){ a[j]とa[j-1]を交換; j--; } j → [1] 3 2 3 i → [2] 2 [3] 1 [4] 4 [5] 必ずa[1]>a[0] になり,ループを脱出 [n]

挿入ソートの実行例 整列前 4 5 5 7 8 1 2 9 3 1回実行後 2回実行後 3回実行後 4 5 5 7 8 1 2 9 3 挿入ソートの実行例     整列前  4 5 5 7 8 1 2 9 3 1回実行後 2回実行後 3回実行後 4 5 5 7 8 1 2 9 3 4回実行後 4 5 5 7 8 1 2 9 3 5回実行後 1 4 5 5 7 8 2 9 3 6回実行後 1 2 4 5 5 7 8 9 3 7回実行後 1 2 4 5 5 7 8 9 3 8回実行後 1 2 3 4 5 5 7 8 9 iの ループ 整列済 ←

挿入ソートの実行例 整列前  4 5 5 7 8 1 2 9 3 1回実行後 4 5 5 7 8 1 2 9 3 2回実行後 4 5 5 7 8 1 2 9 3 3回実行後 4 5 5 7 8 1 2 9 3 4回実行後 4 5 5 7 8 1 2 9 3 5回実行後 1 4 5 5 7 8 2 9 3 6回実行後 1 2 4 5 5 7 8 9 3 7回実行後 1 2 4 5 5 7 8 9 3 8回実行後 1 2 3 4 5 5 7 8 9 iの ループ 整列済 ← 安定なソート

問題2 次のデータを挿入ソートで昇順に並べ替える経過を示しなさい。 a[5] = {9,3,4,1,4};

i j a[0] a[1] a[2] a[3] a[4] 初期状態 9 3 4 1 1 2 3 4

i j a[0] a[1] a[2] a[3] a[4] 初期状態 9 3 4 1 4 4 1 1 9 3 4 1 9 3 2 4 9 1 3 3 4 9 1 3 2 3 4 9 3 1 1 3 9 4 3 1 4

挿入ソートの計算量 全体 O(n2) 比較: ⇒O(n2) 交換:(a[j]<a[j-1])の個数≦ ⇒ O(n2) a [0] i のループ n-1回 i=2 i=3 i=4 i=n a [0] [1] j [2] j のループは 適切な挿入位置で止まる [3] 内側(j)のループ回数 Min:0回 Max:i-1回 平均:約(i-1)/2回 比較:             ⇒O(n2) 全体 O(n2) [n] 交換:(a[j]<a[j-1])の個数≦      ⇒ O(n2)

選択ソート(selection sort) 整列されていない部分から最小要素を選び,先頭と入れかえる処理を繰り返す i (着目位置) 未ソート a [0] [1] [n-1] 1 3 5 9 10 7 20 17 18 入れかえ 整列されていない部分の最小値

選択ソート実行例 最小要素を選択し、それを先頭要素と交換 同様に次の最小要素を順次先頭側要素と交換 6 1 6 3 4 4 8 4 8 3 7 8 8 9 9 7 9 7 8

選択ソートのコード 1 2 3 9 9 7 3 a [0] void selection_sort(int a[], int n) [1] { int i, j, lowest, lowkey; for (i = 0;i < n - 1; i++){ lowest = i; lowkey = a[i]; for (j = i + 1; j < n; j++){ if (a[j] < lowkey){ lowest = j; lowkey = a[j]; } a[i]とa[lowest]を交換; [1] 2 i → [2] 3 9 9 [3] 7 [4] [5] 3 lowest→ j → [n-1]

選択ソートの実行例 整列前 9 3 4 9 7 2 5 8 1 1回実行後 2回実行後 3回実行後 1 2 3 9 7 4 5 8 9 選択ソートの実行例  整列前  9 3 4 9 7 2 5 8 1 1回実行後  2回実行後  3回実行後 1 2 3 9 7 4 5 8 9 4回実行後 1 2 3 4 7 9 5 8 9 5回実行後 1 2 3 4 5 9 7 8 9 6回実行後 1 2 3 4 5 7 9 8 9 7回実行後 1 2 3 4 5 7 8 9 9 8回実行後 1 2 3 4 5 7 8 9 9 iの ループ 整列済 ←

選択ソートの実行例 整列前  9 3 4 9 7 2 5 8 1 1回実行後 1 3 4 9 7 2 5 8 9 2回実行後 1 2 4 9 7 3 5 8 9 3回実行後 1 2 3 9 7 4 5 8 9 4回実行後 1 2 3 4 7 9 5 8 9 5回実行後 1 2 3 4 5 9 7 8 9 6回実行後 1 2 3 4 5 7 9 8 9 7回実行後 1 2 3 4 5 7 8 9 9 8回実行後 1 2 3 4 5 7 8 9 9 iの ループ 整列済 ← 不安定なソート

問題3 次のデータを選択ソートで昇順に並べ替える経過を示しなさい。 a[7] = {9,3,2,1,4,8,7};

i a[0] a[1] a[2] a[3] a[4] a[5] a[6] 初期状態 9 3 2 1 4 8 7 0 1 2 3 4 5

i a[0] a[1] a[2] a[3] a[4] a[5] a[6] 初期状態 9 3 2 1 4 8 7 7 8 4 9 2 3 1 0 7 8 4 9 3 2 1 1 7 8 4 9 3 2 1 2 7 8 9 4 3 2 1 3 9 8 7 4 3 2 1 4 9 8 7 4 3 2 1 5

交換:各iの最後に1回→全体でn-1回 ⇒O(n) 選択ソートの計算量 i のループ n-1回 i=0 i=1 i=2 i=n-2 a [0] [1] j [2] [3] j: n-1回 j: n-2回 j: 1回 [n-1] 全体 O(n2) 比較: ⇒ O(n2) 交換:各iの最後に1回→全体でn-1回 ⇒O(n)

新しいデータを追加してから並べかえるときなど, まとめ  全体の計算量 比較 交換 バブルソート O(n2) n(n-1)/2 回 (a[j]<a[j-1])の個数回 挿入ソート 約n(n-1)/4 回 選択ソート n-1回 挿入ソートは,整列済みのデータに 新しいデータを追加してから並べかえるときなど, ほぼ整列済みのデータのソートが得意

演習問題

演習問題