アルゴリズムと データ構造 第11回 ソート(2): バケットソート,基数ソート 先週の復習 ソートの基本 ソートアルゴリズムの要件 全体の計算量 比較 交換 バブルソート O(n2) n(n-1)/2 回 (a[j]<a[j-1])の 個数回 挿入ソート O(n2) 選択ソート O(n2) (a[j]<a[j-1])の 約n(n-1)/4 回 個数回 n(n-1)/2 回 n-1回 先週の演習問題 解説 i=6 0 1 2 3 4 5 答え: 32 15 53 28 32 67 41 28 53 86 74 67 15 32 74 67 86 41 53 先週の演習問題 先頭から、すでに整列が終 わったとみなされる範囲はもう ソート済みとみなす。 last 解説 k=0 k=2 k=4 k=7 答え: 0 1 2 3 4 5 6 7 32 15 53 15 67 15 28 15 86 15 74 15 15 41 0 1 2 3 4 5 6 7 15 32 28 28 53 67 28 28 86 41 74 41 41 0 1 2 3 4 5 6 7 15 28 32 41 53 67 41 41 86 74 74 0 1 2 3 4 5 6 7 15 28 32 41 53 67 74 86 j 単純ソートアルゴリズムに関する小テスト 第1問 次のプログラムは、バブルソートを行うプラグラムである #include <stdio.h> #define N 6 /* データ数 */ void main(void) { static int a[] = { 80, 41, 35, 90, 40, 20}; int t, i, j; for ( i=0; i< N-1; i++){ for ( j = N-1; j > i; j-- ) { if ( a[j] < a[j-1]) { t = a[j]; a[j] = a[j-1]; a[j-1]= t;} } } } iループにおいて、各iの値のときの処理後、配列a[]の並びがどのように なるかを示せ。 第2問 次のプログラムは、単純挿入ソートを行うプラグラムである #include <stdio.h> #define N 6 void main(void) { static int a[] = { 80, 41, 35, 90, 40, 20}; int t, i, j; for ( i=1; i< N; i++){ for ( j = i-1; j >=0; j-- ) { if ( a[j] > a[j+1]) { t = a[j]; a[j] = a[j+1]; a[j+1]= t;} else break; } } } iループにおいて、各iの値のときの処理後、配列a[]の並びがどのように なるかを示せ。 第3問 次のプログラムは、単純選択ソートを行うプラグラムである # include <stdio.h> #define N 6 void main(void) { static int a[] = { 80, 41, 35, 90, 40, 20}; int t, i, j, min, s; for ( i=0; i< N-1; i++){ min = a[i]; s=i; for ( j = i+1; j <N; j++ ) { if ( a[j] < min ) { min = a[j]; s=j;} } t = a[i]; a[i] = a[s]; a[s] = t; } } iループにおいて、各iの値のときの処理後、配列a[]の並びがどのように なるかを示せ。 小テスト問題の解説 問題1: バブルソートに関する 配列の後ろから先頭に向かってスキャンし,隣接する2項を比較し、後の項 が前の項より小さければ、両項の入れ替えを行うを繰り返す i=0 80 20 41 35 90 40 20 i=1 20 80 35 41 35 90 40 i=2 20 35 40 80 41 40 90 i=3 20 35 40 41 80 41 90 i=4 20 35 40 41 80 90 答え: i=0: { 20 , 80 , 41 , 35 , 90 , 40 } i=1: { 20 , 35 , 80 , 41 , 40 , 90 } i=2: { 20 , 35 , 40 , 80 , 41 , 90 } i=3: { 20 , 35 , 40 , 41 , 80 , 90 } i=4: { 20 , 35 , 40 , 41 , 80 , 90 } 問題2: 単純挿入ソートに関する 0〜(i-1)番目まではすでにソート済 i番目の要素を0〜iの間の適切な位置に挿入する i=1 80 i=2 41 80 i=3 35 41 80 i=4 35 41 80 90 i=5 35 40 41 80 答え: 35 90 40 20 90 40 20 40 20 20 90 i=1: { 41 , 80 , 35 , 90 , 40 , 20 } i=2: { 35 , 41 , 80 , 90 , 40 , 20 } i=3: { 35 , 41 , 80 , 90 , 40 , 20 } i=4: { 35 , 40 , 41 , 80 , 90 , 20 } i=5: { , 35 , 40 , 41 , 80 , 90 } 20 問題3: 単純選択ソートに関する 整列されていない部分から最小要素を選び,先頭と入 れかえる処理を繰り返す i=0 80 20 41 35 90 40 20 i=1 20 41 35 35 90 40 80 i=2 20 35 40 41 90 40 80 i=3 20 35 40 41 90 41 80 i=4 20 35 40 41 80 90 80 答え: i=0: { i=1: { 20 , 41 , 35 , 90 , 40 , 80 } 20 , 35 , 41 , 90 , 40 , 80 } i=2: { 20 , 35 , 40 , 90 , 41 , 80 } i=3: { 20 , 35 , 40 , 41 , 90 , 80 } i=4: { , 35 , 40 , 41 , 80 , 90 } 20 本日の内容 比較によらないソート バケットソート 基数ソート バケットソート (bucket sort) 別名 ビンソート(bin sort) ともいう 計算量 O (n) バケットソートを適用できる条件: n個の要素は整数で0以上m-1以下の値をとるとする。 バケット 0 1 2 m-1 バケットソートの原理 1.値kの要素を入れる箱(バケットB[k]、ただし、 kは0≦k≦m-1)を準備し、各要素A[i]を B[A[i]]に入れる。 B[A[i]] = A[i]; A = {m-1, 0, 1… , 2} 2.バケットをB[0], B[1], …,B[m-1]の順に連結 する。 0 1 B[0] B[1] m-1 B[2] B[m-1] バケットソートの概念図 配列 A キーに 重複がない場合 バケットB [0] 1 [0] A[2] [1] 4 [1] A[0] [2] 0 [2] A[4] [3] 6 [3] [4] 2 [4] 空のバケット A[1] [5] [6] A[3] 最後にデータをバケット から順に取り出し, 配列に戻して整列終了 キーに重複がある場合 バケットB 配列 A [0] 1 [1] 6 [0] A[2] i番目のバケットに要素が 何個入るか分からない ⇒連結リストで表現 [1] A[8] A[6] A[4] A[0] [2] 0 [3] 6 [2] A[9] [4] 1 [5] 5 [3] なし [6] 1 [4] A[7] [7] 4 [5] A[5] [8] 1 [9] 2 [6] A[3] A[1] バケットソートの実現(手順1) バケットB への格納 配列 A [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] 1 6 0 6 1 5 1 4 1 2 バケットB [0] A[2] [1] A[8] [2] A[9] A[6] 空のバケット [3] [4] A[7] [5] A[5] [6] A[3] A[1] A[4] A[0] バケットソートの実現(手順2) バケットB[i]とB[i+1]の要素を連結 (CONCATENATE)する。 B [0] A[2] [1] A[8] [2] A[9] A[6] A[7] [5] A[5] [6] A[3] A[0] この例では,先頭に要素を追加 したが,末尾に追加すれば,順 序関係が維持される⇒安定 [3] [4] A[4] A[1] バケットソートの特徴 計算量O(n) バケットのためのメモリが必要. (所要メモリ量はデータ数nに比例) キーの種類数 m がある程度小さい場合に使用可. 種類数mが大きい場合は現実的でない. 例 int型=4バイト(32ビット) –2147483648~2147483647 種類数は約40億種 基数ソート(radix sort) radix : 基数.基礎として用いる数. 10進法の基数は10 (0から9まで) 16進法の基数は16 (0から15(F)まで) 整列対象となるキーを,いくつかのサブキーに分割 し,下位から上位の順に,サブキーをもとに安定な 整列を行う サブキーの整列には,計算量O(n)の安定なアルゴ リズムを使用 基数ソートの例 基数個のバケットを用意 各バケットは待ち行列(キュー) 基数10で,3桁に分割した場合 バケット B 配列 A [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] 100 602 90 362 128 517 123 454 112 230 231 一の位で バケット ソート [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] 配列 A 100 90 230 231 602 362 112 123 454 517 128 [0] [1] 先頭から [2] 連接 [3] [4] [5] [6] [7] [8] [9] [10] 100 90 230 231 602 362 112 123 454 517 128 基数ソートの例 基数個のバケットを用意 各バケットは待ち行列 基数10で,3桁に分割した場合 配列 A [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] バケット B 100 90 230 231 602 362 112 123 454 517 128 十の位で バケット ソート [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] 配列 A 100 602 112 517 123 128 230 231 454 362 90 [0] [1] 先頭から [2] 連接 [3] [4] [5] [6] [7] [8] [9] [10] 100 602 112 517 123 128 230 231 454 362 90 基数ソートの例 基数個のバケットを用意 各バケットは待ち行列 基数10で,3桁に分割した場合 配列 A [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] 配列 A バケット B 100 602 112 517 123 128 230 231 454 362 90 百の位で バケット ソート [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [0] [1] 100 112 123 128 先頭から [2] 230 231 [3] 連接 362 [4] 454 [5] 517 [6] 602 [7] [8] [9] [10] 90 90 100 112 123 128 230 231 362 454 517 602 基数ソートによる文字列の整列 k文字の文字列において、i番目の文字をキーとして バケットソートを適用することで整列する。 ただし、処理は文字列の末尾から先頭の順に行う。 k=3 さとう ささき さわだ ←i 辞書式順序(lexicographical order) 単語 x = a1a2…akと y = b1b2…bkについて考える. あるiに対し、aj=bj j=1,2,…, i-1で、かつai<biのとき、 x<yと定義する。ただし空文字はどの文字より小さ いとする。 例 ab<ba, abd<aca, bc <bcd あり<りあ, あおい<あじあ, まき <まきば 数字の場合・・・ 300<310 空文字 例(k=3) (基数 128) 一般的な計算機での文字コードの種類数 辞書式順序に 整列できた [0] [1] [2] [0] [1] [2] [0] [1] [2] [0] [1] [2] a c t p a k f m b d a t b d m c p f a k m c k t d a a f b p a a b c d f k m p t n a h u n e o a u i d t e t y y x p g g n h u i a a u o n e d e g g p t t x y y a a e h i n n o u u p t y e g d y x g t n n u a i o e a u h d y g t g x y p t e 基数ソートの特徴 分割数 k とすると,ソートの計算量O(k n) kがデータ数 n より十分小さい場合O(n) バケットのためのメモリが必要. (所要メモリ量はデータ数nに比例) キーのパターンを分割しても,キーの大小関係が 維持される場合に利用可(浮動小数点数は×) 整数や短い文字列のソートに利用 問題 次の3文字の系列を基数ソートで辞書式順序に 並べていく過程を示せ。 ( J O Y ), ( R E D ), ( R U N ), ( M I D ) 1回目 2回目 3回目 解答 ( J O Y ), ( R E D ), ( R U N ), ( M I D ) 1回目 2回目 3回目 ( R E D ) ( R E D ) ( J O Y ) ( M I D ) ( M I D ) ( M I D ) ( R U N ) ( J O Y ) ( R E D ) ( J O Y ) ( R U N ) ( R U N ) まとめ 配列 A バケットソート O(n) 値kの要素を入れる箱(バケット B[k]、ただし、kは0≦k≦m-1)を準 備し、各要素A[i]をB[A[i]]に入れ たあと、バケットの中身を連結する 基数ソート [0] [1] [2] [3] [4] 1 4 0 6 2 バケットB [0] [1] [2] [3] [4] [5] [6] A[2] A[0] A[4] A[1] A[3] O(n) 整列対象となるキーを,いくつか のサブキーに分割し,下位から上 位の順に,サブキーをもとに安定 な整列を行う B U T K I D F A N F A N A N Y B U T K I D A N Y 演習問題 (問1)次の5個の整数 {4, 7, 5, 6, 7}をバケットソートでバ ケットB[i]( 0 ≦ i < 10) を用いて整列する手順を図を 用いて説明せよ。 (問2)次の3文字の系列を基数ソートで辞書式順序に並べて いく過程を示せ。 (B U T ), 1回目 ( F A N ), 2回目 ( A N Y ), 3回目 ( K I D ) 名前と学籍番号をご記入のうえ、解答用紙(A4)を提出する 提出先: 工学部電子情報実験研究棟5階 NO.5506室のドアのポストに入れてください 締め切り時間: 来週月曜日(6月30日) 午前9時まで
© Copyright 2024 ExpyDoc