第12回 ソート(3): シェルソート、クイックソート

Slides:



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

離散システム特論 整列(sorting)アルゴリズム 2.
データ構造とアルゴリズム論 第5章 整列(ソート)のアルゴリズム
ヒープソートの演習 第13回.
アルゴリズムイントロダクション第2章 主にソートに関して
4.ソート 4-1.ソート問題について 4-2.簡単なソートアルゴリズム 4-3.高度なソートアルゴリズム
アルゴリズムとデータ構造 2012年6月27日
高速ソートと 安定結婚問題 平成24年12月14日.
アルゴリズムとデータ構造 第8回 ソート(3).
第10回 整列 ~ バブルソート,挿入ソート,選択ソート~
第11回 整列 ~ シェルソート,クイックソート ~
データ構造とアルゴリズム論 第5章 整列(ソート)のアルゴリズム
第11回 整列 ~ バケットソート,基数ソート,ヒープソート~
2009/10/30 整列アルゴリズム (2) 第5講: 平成21年10月30日 (金) 4限 E252教室 コンピュータアルゴリズム.
データ構造とアルゴリズム論 第6章 探索のアルゴリズム
プロセッシング入門3 初歩のプログラミング.
アルゴリズムとデータ構造 第6回演習解答 2015/11/18実施 アルゴリズムとデータ構造 2015.
情報知能学科「アルゴリズムとデータ構造」
第10回 ソート(1):単純なソートアルゴリズム
情報工学概論 (アルゴリズムとデータ構造)
情報処理Ⅱ 2005年12月9日(金).
担当:青木義満 情報工学科 3年生対象 専門科目 システムプログラミング システムプログラミング プロセス間通信(パイプ) 担当:青木義満
アルゴリズムとデータ構造 補足資料7-3 「単純選択ソートselsort.c」
データ構造とアルゴリズム 分割統治 ~ マージソート~.
岩井 儀雄 コンピュータ基礎演習  ー探索、整列ー 岩井 儀雄
エージェントを管理するボスの苦悩 問題 n人のエージェントを部下に持つボスがいる. エージェントは出張・帰還を頻繁に繰り返す.
ヒープソートの復習.
第11回 整列 ~ シェルソート,クイックソート ~
プログラミング基礎a 第8回 プログラムの設計 アルゴリズムとデータ構造
定兼邦彦 今井浩 東京大学理学系研究科 情報科学専攻
2009/11/6 整列アルゴリズムの復習 第6講: 平成21年11月6日 (金) 4限 E252教室 コンピュータアルゴリズム.
情報工学概論 (アルゴリズムとデータ構造)
アルゴリズムとデータ構造1 2005年7月15日
ソートアルゴリズムの種類 選択ソート (selection sort) バブルソート (bubble sort)
情報工学概論 (アルゴリズムとデータ構造)
クイックソート.
わんくま同盟茶藝部顧問 Microsoft MVP for VC episthmh
データ構造とアルゴリズム論 第6章 整列(ソート)のアルゴリズム
アルゴリズムとデータ構造 第3章 ヒープ 6月10日分
第9回 優先度つき待ち行列,ヒープ,二分探索木
アルゴリズムとデータ構造1 2005年7月1日
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」
プログラミング基礎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日
アルゴリズムとプログラミング (Algorithms and Programming)
文字列へのポインタの配列 static char *lines[MAXLINES]; lines[0] NULL
データ構造とアルゴリズム (第5回) 静岡大学工学部 安藤和敏
第9回 優先度つき待ち行列,ヒープ,二分探索木
アルゴリズムとデータ構造 2012年7月2日
アルゴリズムとプログラミング (Algorithms and Programming)
バブルソート,バケツソート,クイックソート
アルゴリズムとデータ構造 2011年6月28日
ヒープソートの復習 第12回.
アルゴリズムとデータ構造 2013年7月2日
ソートのプログラムの流れ 配列の中身を小さい順に並び替える a[1],a[2],…a[n]の値を順に出力する
平面走査法を使った 一般線分の 交点列挙アルゴリズム
アルゴリズムとデータ構造 2012年6月25日
参考:大きい要素の処理.
知能情報工学演習I 第11回(後半第5回) 課題の回答
プログラミング論 バイナリーサーチ 1.
Presentation transcript:

第12回 ソート(3): シェルソート、クイックソート アルゴリズムと データ構造 第12回 ソート(3): シェルソート、クイックソート

先々週の復習 O(n2)のソート バブルソート 挿入ソート 選択ソート 未ソート バブルソート 配列の後ろから先頭に向かってスキャンし,隣り合う2つの要素の大小関係が逆であったら入れかえる 挿入ソート 現在処理対象となっているデータを,整列済みのデータ列内の適切な位置に挿入する 選択ソート 整列されていない部分から最小要素を選び,先頭と入れかえる処理を繰り返す 1 3 5 9 10 7 20 17 6 3 5 8 10 11 7 ソート済 未ソート 1 3 5 9 10 7 20 17 18 入れかえ 最小値

先週の復習 バケットソート O(n) 基数ソート O(n) A[2] A[0] A[4] A[1] A[3] 1 4 6 2 配列 A バケットB [1] [2] [3] [4] [0] [5] [6] バケットソート  O(n) 値kの要素を入れる箱(バケットB[k]、ただし、kは0≦k≦m-1)を準備し、各要素A[i]をB[A[i]]に入れたあと、バケットの中身を連結する 基数ソート O(n) 整列対象となるキーを,いくつかのサブキーに分割し,下位から上位の順に,サブキーをもとに安定な整列を行う B U T K I D A N Y F A N F A N B U T A N Y K I D

先週の演習問題 (問1)次の5個の整数 {4, 7, 5, 6, 7}をバケットソートでバケットB[i]( 0 ≦ i < 10) を用いて整列する手順を図を用いて説明せよ。

4 7 5 6 B [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] 4 5 6 7 問1 解答例1 (抽象的な説明例) 4 7 5 6 A [0] [1] [2] [3] [4] 5個の整数が配列Aに格納 されているものとする バケットBにデータを格納する B [0] [1] [2] [3] [4] A[0] A[2] A[3] A[1] A[4] [5] [6] [7] [8] [9] バケットの先頭から順に 取り出し、配列Aに戻す 4 5 6 7 A’ [0] [1] [2] [3] [4]

問1 解答例2 (ポインタを用いた実装を想定した例) 問1 解答例2 (ポインタを用いた実装を想定した例) バケットBにデータを格納する 4 7 5 6 A [0] [1] [2] [3] [4] B [0] [1] [2] [3] [4] A[0] [5] A[2] [6] A[3] バケットの先頭から順に取り出し、配列Aに戻す [7] A[4] A[1] 4 5 6 7 A’ [0] [1] [2] [3] [4] [8] [9]

(B U T ), ( F A N ), ( A N Y ), ( K I D ) (問2)次の3文字の系列を基数ソートで辞書式順序に並べていく過程を示せ。 (B U T ), ( F A N ), ( A N Y ), ( K I D ) 1回目 2回目 3回目

問2 解答 1回目 2回目 3回目 K I D F A N A N Y F A N K I D B U T B U T A N Y

本日の内容 シェルソート クイックソート

シェルソート(Shell sort) 1959年に D. L. Shellが発表したアルゴリズム 挿入ソートを変形 計算量O(n1.25)~O(n1.5) 安定ではない

シェルソート 単純挿入ソートの特徴 シェルソートの考え方 ソート済みに近い場合は高速 挿入先が遠く離れていると移動回数が増大 1 1 1 2 2 2 3 3 4 3 4 4 5 5 5 6 シェルソートの考え方 単純挿入ソートの長所を生かしつつ、回数の多い移動を避ける 最初にまずグループ化を行い、グループ内で大まかにソート(地ならし) グループを次第に小さくしていき、最終的に単純挿入ソートを行ってソート完了 前処理を含めても、移動回数が少なくてすみ、全体として高速化

シェルソートの実例 4-ソート 2-ソート 1-ソート 8 8 7 1 1 3 4 4 2 2 7 7 8 6 6 3 4 3 5 5 3

シェルソート シェルソートのプログラム for (h = n / 2; h > 0; h / 2) for (i = h; i < n; i++) { int tmp = a[i]; for (j = i - h; j >= 0 && a[j] > tmp; j -= h) a[j + h] = a[j]; a[j + h] = tmp; }

シェルソート 増分の選択 ある値から減少して1になればよい 増分のとり方によっては、同じグループ内でのみソートして、グループ分けが十分に機能しなくなる 増分が互いに倍数にならないようにする h = ・・・、121、40、13、4、1 1から始め、3倍して1を足していく 最初が大きすぎても効果なし:n / 9を超えない値

シェルソート 適切増分シェルソートのプログラム for (h = 1; h < n / 9; h = h * 3 + 1) ; for (i = h; i < n; i++) { int tmp = a[i]; for (j = i - h; j >= 0 && a[j] > tmp; j -= h) a[j + h] = a[j]; a[j + h] = tmp; }

練習問題 以下のデータをシェルソートで昇順に整列しなさい 整列の間隔は4、2、1の順で減らすこと。 10, 5 , 4, 27, 2, 6, 3, 20, 1, 0, 8, 9, 7, 23, 13, 42

解答 10 5 4 27 2 6 3 20 1 0 8 9 7 23 13 42 4ずつ離れたものをソートした結果 1 0 3 9 2 5 4 20 7 6 8 27 10 23 13 42 1 0 3 9 2 5 4 20 7 6 8 27 10 23 13 42 2ずつ離れたものをソートした結果 1 0 2 5 3 6 4 9 7 20 8 23 10 27 13 42 1ずつ離れたものをソートした結果 0 1 2 3 4 5 6 7 8 9 10 13 20 23 27 42

シェルソート(Shell sort)のまとめ 挿入ソートを変形 計算量O(n1.25)~O(n1.5) 安定ではない

クイックソート クイックソートとは ただし,最悪の場合O (n2) 1962年に C. A. R. Hoareが発表したアルゴリズム 内部整列アルゴリズムの中で最速 不安定な整列アルゴリズム ある要素を決め、その要素より大きいグループと小さいグループに分類 ある要素:枢軸 各グループで枢軸を決め直して同じように分割 計算量O(n log n) ただし,最悪の場合O (n2)

クイックソートの原理 ソートする範囲のデータから適当な軸要素(枢軸、pivot) Xを選ぶ。 小グループと大グループ各々に上記1.と2.を適用する。 各々のグループが分割できなくなるまで分割を繰り返す。 実行例1 8 3 6 5 5 4 7 2 1 4 2 2 3 1 5 6 6 8 7 1 2 2 4 4 3 5 5 6 8 8 7 1 2 3 4 5 6 7 8

分割の手順 枢軸をx、配列左端をpl、配列右端をprとし pl位置の要素がxより大きくなるまでplを右に移動 pr位置の要素がxより小さくなるまでprを左に移動 pl、pr両位置の要素を交換 操作を続け、plとprの位置が交差した時点で終了 配列左端からpl位置の1つ前まで:枢軸より小さい集合 pr位置の1つ後から配列右端まで:枢軸より大きい集合 実行例2 5 5 3 7 7 1 1 4 4 2 6 6 6 2 2 6 3 7 3 9 9 8 8 pl pr 枢軸以下 枢軸以上

クイックソート ソートの手順 分割されたグループそれぞれに、同じ処理を再度適用して再分割 分割されたグループの要素数が1になった時点で分割終了 一種の分割統治法:再帰で簡単に実現

クイックソートのコード void quicksort(int l, int r, int A[]) { int k; /* 枢軸より大きい部分の開始位置 */ 軸要素を決める; if (キーがすべて同じ) 終了; xより小さい部分と大きい部分に分割し, 大きい部分の先頭の位置kを返す; quicksort(l, k – 1,A); /* 小さい部分を整列 */ quicksort(k, r, A); /* 大きい部分を整列 */ }

枢軸の選択 枢軸の選び方がクイックソートの効率に影響 できるだけ配列の値の中央値が望ましい 配列の値の最小値または最大値を選ぶと最悪 できるだけ配列の値の中央値が望ましい ただし厳密に求める処理に時間がかかると本末転倒 方針1:先頭要素、中央要素、最後尾要素の3値の中間値を使う 方針2:方針1に加え、3値をソートして、中央要素と最後尾1つ前の値を入れ替え、ソート範囲を3要素分絞る 先頭は必ず枢軸以下、最後尾とその手前は必ず枢軸以上の値になっているので、それぞれの内側をソート範囲とすればよくなる

実行例3 X= 3の場合 pl→ ←pr A[0] A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8] A[9] 3 1 4 5 9 2 6 Start (1) 2 1 4 5 9 3 6 (2) 2 1 4 5 9 3 6 分割終了 pr = 2 pl = 3 pl, pr : カーソル v : 枢軸

実行例3:各々のグループをさらに分割 2 1 4 5 9 3 6 レベル2 1 2 4 3 9 6 5 1 2 4 3 9 6 5 レベル3 a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] 2 1 4 5 9 3 6 レベル2 X=2 1 2 X=5 4 3 9 6 5 1 2 終了 4 3 9 6 5 レベル3 X=4 3 4 X=9 5 6 9 キーが 全て同じ 3 4 終了 5 6 9 終了 レベル4 X=6 5 6 5 6 終了 レベル5 ソート終了

クイックソートの計算時間 分割の段数≒log2 n 各段での時間 O ( n ) 平均時間 → O ( n log n )

最悪の場合 = { n ( n - 1) } / 2 比較回数 7 6 5 4 3 2 1 Σi → O ( n 2 ) n= 8 n= 8 比較回数 7 : 即ち n-1 6 5 4 3 2 1 選択ソートの実行と同じようになり Σi i=1 n-1 = { n ( n - 1) } / 2 → O ( n 2 )

クイックソートのまとめ ただし,最悪の場合O (n2) 1962年に C. A. R. Hoareが発表したアルゴリズム 内部整列アルゴリズムの中で最速 不安定な整列アルゴリズム ある要素を決め、その要素より大きいグループと小さいグループに分類 ある要素:枢軸 各グループで枢軸を決め直して同じように分割 計算量O(n log n) ただし,最悪の場合O (n2)

ソート全体のまとめ バブルソート O(n2) 挿入ソート 選択ソート バケットソート O(n) 基数ソート シェルソート クイックソート 名称 計算量 内部/外部 安定/不安定 備考 バブルソート O(n2) 内部 安定 挿入ソート 選択ソート 不安定 バケットソート O(n) データに制限有 基数ソート シェルソート O(n1.25)~ O(n1.5) クイックソート O(n log n)  最悪O(n2)

演習問題 次の配列を、クイックソートにより並べ替える。 並べ替え領域の左端の添え字を pl、右端の添え字を pr と設定したとき、枢軸は (pl+pr)/2(小数点以下切り捨て)で示される添え字の位置とする(この配列では添え字 5 の 59)。ここで 1. pl 位置の値が枢軸の値以上になるまで pl を右へずらす。 2. pr 位置の値が枢軸の値以下になるまで pr を左へずらす。 3. pl 位置の値と pr 位置の値を入れ替える。 4. pl と pr が交差して入れ替わるまで、1. から 3. までを繰り返す。 という操作を行うと、配列は となり、添え字 0 から 5 までの集合と 6 から 11 までの集合に分割される。このとき、以下の問いに答えよ。 (1) 添え字 0 から 5 までの集合において、pl、pr および枢軸の位置を再設定し、同様に分割したとき、分割後の配列の並びと pl、pr の添え字位置を示せ。 (2) 添え字 6 から 11 までの集合において、pl、pr および枢軸の位置を再設定し、同様に分割したとき、分割後の配列の並びと pl、pr の添え字位置を示せ。