100 likes | 171 Views
2005 年度 データ構造とアルゴリズム 第 7 回 「基礎的な整列アルゴリズム」. 西尾 信彦 nishio@cs.ritsumei.ac.jp 立命館大学情報理工学部 情報システム学科. 整列とは. 何らかの ( 全 ) 順序関係が成立するレコード群を,その順序関係に従って並べ換えること 数字の昇順,降順や文字列の辞書順 ここでは,整数データのみによるレコードが n 個あるとき,その整数をキーとして整列させることを考える. 単純な整列アルゴリズム. 先頭レコードを残りの全てのレコードと順に比べる より小さいレコードを発見したら交換する
E N D
2005年度データ構造とアルゴリズム第7回「基礎的な整列アルゴリズム」2005年度データ構造とアルゴリズム第7回「基礎的な整列アルゴリズム」 西尾 信彦 nishio@cs.ritsumei.ac.jp 立命館大学情報理工学部 情報システム学科
整列とは • 何らかの(全)順序関係が成立するレコード群を,その順序関係に従って並べ換えること • 数字の昇順,降順や文字列の辞書順 • ここでは,整数データのみによるレコードが n 個あるとき,その整数をキーとして整列させることを考える
単純な整列アルゴリズム • 先頭レコードを残りの全てのレコードと順に比べる • より小さいレコードを発見したら交換する • 結果,先頭に最も小さいレコードが置かれる • 残りのレコードに対し,同様のことを繰りかえす. void sort(void) { int i, j; for (i = 0; i < n-1; i++) { for (j = i+1; j < N; j++) { if (arr[i] > arr[j]) { swap(i, j); } } } }
単純法の計算量 void sort(void) { int i, j; for (i = 0; i < n-1; i++) { for (j = i+1; j < N; j++) { if (arr[i] > arr[j]) { swap(i, j); } } } } • 二重のループ • 外側は0から N-2 • 全体で n(n-1)/2 回 • 比較演算の回数はループの回数と同じ • 交換は最悪ループ回数,平均はその半分 • O(n2)の計算量
バブルソート void sort(void) { int i, j; for (i = N; i > 1; --i) { for (j = 1; j < i; j++) { if (arr[j-1] > arr[j]) { swap(j-i, j); } } } } • 隣りあうレコード同士を比較し逆転していれば交換する • このままでは計算量は単純ソートと同じ
バブルソートの改良 1 void sort(void) { int i, j, flag; for (i = N; i > 1; --i) { flag = 1; for (j = 1; j < i; j++) { if (arr[j-1] > arr[j]) { swap(j-i, j); flag = 0; } } if (flag) return; } } • ループの途中で整列が完了していることを感知する • 交換が一度も行なわれなければもう整列している • 計算量は0.01%程度の改良
バブルソートの改良 2 void sort(void) { int i, j, last; for (i = N; i > 1; i = last) { last = 0; for (j = 1; j < i; j++) { if (arr[j-1] > arr[j]) { swap(j-i, j); last = j; } } } } • 最後に交換が行なわれた箇所を記憶 • それ以降は比較しない • 計算量は0.04%程度の改良
単純法の改良:選択整列法 • 1回のループで交換は1度のみに限定する • swap関数を呼び出す代りに交換候補としてmin変数に保存する • 比較はループの回数と同じ n(n-1)/2回 • 交換はn-1回に固定 • その代りにminへの代入が増えている • 関数呼出しよりは安価
挿入整列法 • 先頭 [未整列レコード][整列レコード]最後 • と見たてて,先頭レコードを整列レコードのどこに挿入するかを決定し,挿入する. • 始めは整列レコードは最後レコードの1個 • その右に挿入するか,左に挿入するかを決定する • 挿入のために配列内を移動させるのが手間 • ほぼ整列しているレコードに対して有効
アルゴリズムの特性 • あまり大差ないが,選択整列法の交換が O(n) であるのは大きい • 比較演算に対して交換の手間が大きなレコードでは効果が大きい • 巨大なデータ本体を持つレコードとか • ほぼ整列しているデータの場合には挿入整列法が有利 • ほぼ O(n)の計算量