第10回 整列 ~ バブルソート,挿入ソート,選択ソート~

Slides:



Advertisements
Similar presentations
逐次ソート 2011/05/16. ソート(sort) 順序集合の要素a 1 … a n の上下関係を整 える 一般的には、整数の集合 N を考えればよ い ソートの計算量が問題となる どのような入力に対し、どのようなアル ゴリズムが最適か?
Advertisements

データ構造とアルゴリズム 平成20年度 前期 2年生必修  水曜日 3-4時限.
離散システム特論 整列(sorting)アルゴリズム 2.
データ構造とアルゴリズム論 第5章 整列(ソート)のアルゴリズム
ヒープソートの演習 第13回.
アルゴリズムイントロダクション第2章 主にソートに関して
4.ソート 4-1.ソート問題について 4-2.簡単なソートアルゴリズム 4-3.高度なソートアルゴリズム
アルゴリズムとデータ構造 2012年6月27日
第12回 ソート(3): シェルソート、クイックソート
アルゴリズムとデータ構造 第8回 ソート(3).
第11回 整列 ~ シェルソート,クイックソート ~
データ構造とアルゴリズム論 第5章 整列(ソート)のアルゴリズム
アルゴリズムとデータ構造 2013年6月18日
アルゴリズムとデータ構造1 2005年7月8日
第11回 整列 ~ バケットソート,基数ソート,ヒープソート~
2009/10/30 整列アルゴリズム (2) 第5講: 平成21年10月30日 (金) 4限 E252教室 コンピュータアルゴリズム.
データ構造とアルゴリズム論 第6章 探索のアルゴリズム
アルゴリズムとデータ構造 第6回演習解答 2015/11/18実施 アルゴリズムとデータ構造 2015.
4.整列のアルゴリズム.
第10回 ソート(1):単純なソートアルゴリズム
アルゴリズムとデータ構造 2012年6月14日
データ構造とアルゴリズム 分割統治 ~ マージソート~.
岩井 儀雄 コンピュータ基礎演習  ー探索、整列ー 岩井 儀雄
ヒープソートの復習.
アルゴリズムとデータ構造 2011年6月14日
アルゴリズム入門.
アルゴリズムとデータ構造 第7回探索のためのデータ構造(1) 2015/11/18 アルゴリズムとデータ構造 2015.
第11回 整列 ~ シェルソート,クイックソート ~
第3回 配列,構造体,ポインタ ~ データ構造について学ぶための基礎~
二分探索木によるサーチ.
Cプログラミング演習 中間まとめ2.
2009/11/6 整列アルゴリズムの復習 第6講: 平成21年11月6日 (金) 4限 E252教室 コンピュータアルゴリズム.
アルゴリズムとデータ構造1 2006年6月16日
情報工学概論 (アルゴリズムとデータ構造)
アルゴリズムとデータ構造1 2005年7月15日
ソートアルゴリズムの種類 選択ソート (selection sort) バブルソート (bubble sort)
アルゴリズムとデータ構造勉強会 第6回 スレッド木
情報工学概論 (アルゴリズムとデータ構造)
わんくま同盟茶藝部顧問 Microsoft MVP for VC episthmh
データ構造とアルゴリズム論 第6章 整列(ソート)のアルゴリズム
第9回 優先度つき待ち行列,ヒープ,二分探索木
データ構造と アルゴリズム 第七回 知能情報学部 新田直也.
基本情報技術概論(第6回) 埼玉大学 理工学研究科 堀山 貴史
Cプログラミング演習 第10回 二分探索木.
アルゴリズムとプログラミング (Algorithms and Programming)
データ構造とアルゴリズム論 第5章 整列(ソート)のアルゴリズム
データ構造とアルゴリズム論 第5章 整列(ソート)のアルゴリズム
プログラミング 4 整列アルゴリズム.
2009/10/23 整列アルゴリズム (1) 第4講: 平成21年10月23日 (金) 4限 E252教室 コンピュータアルゴリズム.
プログラミング 4 探索と計算量.
データ構造とアルゴリズム論 第5章 整列(ソート)のアルゴリズム
プログラミング 4 木構造とヒープ.
アルゴリズムとデータ構造1 2006年7月11日
アルゴリズムとデータ構造 2011年6月23日
15.cons と種々のデータ構造.
文字列へのポインタの配列 static char *lines[MAXLINES]; lines[0] NULL
データ構造とアルゴリズム (第5回) 静岡大学工学部 安藤和敏
第9回 優先度つき待ち行列,ヒープ,二分探索木
アルゴリズムとプログラミング (Algorithms and Programming)
バブルソート,バケツソート,クイックソート
基本情報技術概論(第6回) 埼玉大学 理工学研究科 堀山 貴史
ヒープソートの復習 第12回.
情報工学概論 (アルゴリズムとデータ構造)
ソートのプログラムの流れ 配列の中身を小さい順に並び替える a[1],a[2],…a[n]の値を順に出力する
平面走査法を使った 一般線分の 交点列挙アルゴリズム
アルゴリズムとデータ構造 2012年6月25日
ヒープソート.
参考:大きい要素の処理.
プログラミング論 バイナリーサーチ 1.
ファーストイヤー・セミナーⅡ 第10回 if文による選択処理(2).
Presentation transcript:

第10回 整列 ~ バブルソート,挿入ソート,選択ソート~ データ構造とアルゴリズム 第10回 整列 ~ バブルソート,挿入ソート,選択ソート~

子が2つとも親より小さいときは,小さい方の子と交換 解答(1):半順序木(ヒープ) 子が2つとも親より小さいときは,小さい方の子と交換 2, 7, 4, 9, 7, 4, 12, 10, 13, 11 12 7 4 2 11 9 13 10 4 7 4 9 7 11 12 10 13 DeleteMinした結果

解答(2) 2分探索木 左部分木<根<右部分木 行きがけ順 1 3 2 3 1 2 2 1 3 通りがけ順 1 2 3 帰りがけ順 2 3 1 1 3 2 3 1 2分探索木を 通りがけ順に なぞるとデータが昇順に並ぶ 3 1 2 2

補足:ヒープとヒープメモリ 12 7 4 2 11 9 13 10 半順序木:節点vの優先度がvの子の優先度より必ず小さいか等しい 補足:ヒープとヒープメモリ   半順序木:節点vの優先度がvの子の優先度より必ず小さいか等しい heap [英語] つみかさねた山のようなもの,かたまり アルゴリズムの分野で 「ヒープ」という場合は,半順序木またはそれを配列で表現したものを指す 計算機の構造の話ででてくる「ヒープメモリ」or「ヒープ領域」とは意味が異なるので混同しないこと 12 7 4 2 11 9 13 10 静的メモリ領域 スタック領域 ヒープ領域

本日の内容 整列アルゴリズム 単純な整列アルゴリズム バブルソート 挿入ソート 選択ソート

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

昇順、降順 (ascending order) (descending order) 数値の場合、 ものから ものへ 1,3,5,8,10 昇順、降順       (ascending 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 (      )

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万

内部ソートと外部ソート 主記憶 (メモリ) ランダム 外部記憶 (磁気テープなど) シーケンシャル 主記憶 (メモリ) ランダム 外部記憶 整列したい データ 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つ以上ある場合に,整列前の位置関係が整列後も保たれているアルゴリズムを という 安定な整列    同じキーをもつレコードが2つ以上ある場合に,整列前の位置関係が整列後も保たれているアルゴリズムを              という 5A 7 4 8 5B 3 2  安定なアルゴリズムによる整列結果 不安定なアルゴリズムによる整列結果 2 3 4 5A 5B 7 8  2 3 5B 5A 7 8 

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

バブルソート(bubble sort) 7 3 配列の後ろから先頭に向かってスキャンし, 5 9 6 4 8 2 8 9 2 9 2 a [0] 7 [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--){ } [1] [2] [3] [4] [5] j → [n-1]

バブルソートの実行例 a[0] a[1] a[8] 整列前 9 3 2 1 4 7 5 5 8 i=0のあと i=1のあと バブルソートの実行例   a[0] a[1] a[8] 整列前  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 整列済 ←

バブルソートの実行例 a[0] a[1] a[8] 整列前 9 3 2 1 4 7 5 5 8 バブルソートの実行例   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 整列済 ←

バブルソートの実行例 a[0] a[1] a[8] 整列前 9 3 2 1 4 7 5 5 8 バブルソートの実行例   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 整列済 ← 安定なソート

問題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 のループ n-1回 i=0 i=1 i=n-2 a [0] [1] [2] [3] j: n-1回 j: n-2回 j: 1回 [n-1] 比較: ⇒ O(n2) 交換:(a[j]<a[j-1])の個数: 逆順の場合、比較の回数分交換も起こる ⇒ O(n2)

挿入ソート(insertion sort) ソート済 a [0] [1] [i-1] [i] [n-1] 3 5 8 10 11 7

j >= 1を満たさないのでwhileループを抜ける 挿入ソートの疑似コード  j >= 1を満たさないのでwhileループを抜ける a[0] 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]){ j--; } j → i → [1] 3 [2] 1 [3] 4 [4] [n-1]

j >= 1を満たさないのでwhileループを抜ける 挿入ソートの疑似コード  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] 番兵を使う場合 i → [2] 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--; } 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

挿入ソートの計算量 全体 O(n2) 比較: ⇒O(n2) 交換:(a[j]<a[j-1])の個数≒ c・n ⇒ O(n) 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])の個数≒ c・n ⇒ O(n)

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

選択ソートの疑似コード 1 2 3 9 9 7 3 a [0] void selection_sort(int a[], int n) { 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[5] = {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の最後に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) 交換:各iの最後に1回→全体でn-1回 ⇒O(n)

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

次回の予定 バケットソート 基数ソート ヒープソート

本日の課題(1) 下記の疑似コードにしたがってソートする時,外側のforループの各 i での配列aの内容を記せ. 配列の要素数nは6とし,配列aの初期値は先頭から順に{ 8, 4, 3, 9, 1, 5 }であるものとする. void 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]を交換; }

付録:C言語の豆知識(1) 三項演算子“? :” x = (a > b)? a : b; ()内の条件が真なら:の左側 ()内の条件が偽なら:の右側 の値が返される. a=5, b=3 なら,条件が真なのでxに5が入る. #define MAX(a, b) (a > b)? (a) : (b)