酒居敬一(sakai.keiichi@kochi-tech.ac.jp) アルゴリズムとデータ構造1 2006年7月11日 酒居敬一(sakai.keiichi@kochi-tech.ac.jp) http://www.info.kochi-tech.ac.jp/k1sakai/Lecture/ALG/2006/index.html.

Slides:



Advertisements
Similar presentations
山元進.  for 文  while 文  do ~ while 文  文のネスト  break 文  continue 文.
Advertisements

離散システム特論 整列(sorting)アルゴリズム 2.
アルゴリズムとデータ構造 2012年6月27日
第12回 ソート(3): シェルソート、クイックソート
アルゴリズムとデータ構造1 2008年7月22日
第11回 整列 ~ シェルソート,クイックソート ~
アルゴリズムとデータ構造 2013年6月18日
アルゴリズムとデータ構造1 2005年7月8日
アルゴリズムとデータ構造 2010年7月5日
2009/10/30 整列アルゴリズム (2) 第5講: 平成21年10月30日 (金) 4限 E252教室 コンピュータアルゴリズム.
4-3:高度なソートアルゴリズム① (分割統治法にもとづくソート)
第9回 並び替えアルゴリズム ~さまざまなアルゴリズムを比較しよう~.
アルゴリズムとデータ構造 2012年6月14日
アルゴリズムとデータ構造 2011年6月13日
アルゴリズムとデータ構造 補足資料7-3 「単純選択ソートselsort.c」
データ構造とアルゴリズム 分割統治 ~ マージソート~.
岩井 儀雄 コンピュータ基礎演習  ー探索、整列ー 岩井 儀雄
データ構造と アルゴリズム 第八回 知能情報学部 新田直也.
アルゴリズムとデータ構造 2012年7月5日
アルゴリズムとデータ構造 2011年6月14日
アルゴリズムとデータ構造 2011年6月20日
アルゴリズム入門.
第11回 整列 ~ シェルソート,クイックソート ~
アルゴリズムとデータ構造 2011年6月30日
アルゴリズムとデータ構造 2012年6月28日
アルゴリズムとデータ構造 2011年6月27日
2009/11/6 整列アルゴリズムの復習 第6講: 平成21年11月6日 (金) 4限 E252教室 コンピュータアルゴリズム.
アルゴリズムとデータ構造 2013年7月16日
アルゴリズムとデータ構造1 2006年7月4日
アルゴリズムとデータ構造1 2006年6月16日
アルゴリズムとデータ構造1 2005年7月15日
アルゴリズムとプログラミング (Algorithms and Programming)
ソートアルゴリズムの種類 選択ソート (selection sort) バブルソート (bubble sort)
情報工学概論 (アルゴリズムとデータ構造)
わんくま同盟茶藝部顧問 Microsoft MVP for VC episthmh
アルゴリズムとデータ構造1 2005年7月1日
クイックソート.
大岩 元 慶応大学環境情報学部 再帰 データ構造とプログラミング(8) 大岩 元 慶応大学環境情報学部
アルゴリズムとデータ構造 2012年7月17日
アルゴリズムとデータ構造1 2009年7月9日
アルゴリズムとデータ構造1 2005年7月5日
アルゴリズムとプログラミング (Algorithms and Programming)
復習+α JBuilderの使い方を思い出す。 配列とGUI 再帰とマージソート 木と二分木の探索
プログラミング 4 整列アルゴリズム.
アルゴリズムとデータ構造1 2005年6月24日
アルゴリズムとデータ構造 2010年6月21日
2009/10/23 整列アルゴリズム (1) 第4講: 平成21年10月23日 (金) 4限 E252教室 コンピュータアルゴリズム.
アルゴリズムとデータ構造 2010年7月26日
アルゴリズムとデータ構造 2011年6月23日
プログラミング演習Ⅲ- Sorting Quick Sort and Merge Sort
アルゴリズムとプログラミング (Algorithms and Programming)
データ構造とアルゴリズム (第5回) 静岡大学工学部 安藤和敏
アルゴリズムとデータ構造1 2006年7月4日
アルゴリズムとデータ構造 2012年7月2日
アルゴリズムとデータ構造 2012年6月11日
アルゴリズムとデータ構造 2011年7月11日
アルゴリズムとプログラミング (Algorithms and Programming)
アルゴリズムとデータ構造1 2008年7月24日
アルゴリズムとデータ構造 2011年6月28日
アルゴリズムとデータ構造1 2006年6月23日
アルゴリズムとデータ構造 2013年7月1日
アルゴリズムとデータ構造1 2009年7月2日
計算機プログラミングI 第4回 2002年10月31日(木) 問題解決とアルゴリズム クラスメソッドと手続きの抽象化 最大公約数
アルゴリズムとデータ構造 2013年7月2日
ソートのプログラムの流れ 配列の中身を小さい順に並び替える a[1],a[2],…a[n]の値を順に出力する
アルゴリズムとデータ構造 2012年6月25日
アルゴリズムとデータ構造 2012年6月21日
アルゴリズムとデータ構造1 2005年7月12日
アルゴリズムとデータ構造1 2007年7月6日
プログラミング論 バイナリーサーチ 1.
Presentation transcript:

酒居敬一(sakai.keiichi@kochi-tech.ac.jp) アルゴリズムとデータ構造1 2006年7月11日 酒居敬一(sakai.keiichi@kochi-tech.ac.jp) http://www.info.kochi-tech.ac.jp/k1sakai/Lecture/ALG/2006/index.html

バブルソート > 8 3 > 10 8 > 10 3 < 8 10 > 10 5 < 10 15 > 15 5 < 10 15 > 15 12 < 15 32 > 15 1 > 32 12 > 32 1 > 15 6 > 32 6 < 15 24 > 32 24 整列済み 10 1 8 3 15 5 32 12 6 24 10 8 8 3 10 3 10 5 15 5 15 12 15 1 32 12 32 1 15 6 32 6 24 32 24 入れ替え 入れ替え 入れ替えない 入れ替え 入れ替えない 入れ替え 入れ替えない 入れ替え 入れ替えない 入れ替え 入れ替え 入れ替え 入れ替え 入れ替え 入れ替えない 入れ替え 入れ替え 残りも同様に整列させると… 10 1 8 3 15 5 32 12 6 24

配列要素どおしの入れ替えが無くなれば終了 public final class BubbleSort { public static void sort(int[] anyTargetIntegers) if(null == anyTargetIntegers){ throw new NullPointerException(); } BubbleSort.print(anyTargetIntegers); boolean isChanged = false; int limit = anyTargetIntegers.length - 1; while(true){ isChanged = false; for(int count = 0; count < limit; count++){ if(anyTargetIntegers[count] > anyTargetIntegers[count+1]){ int temp = anyTargetIntegers[count]; anyTargetIntegers[count] = anyTargetIntegers[count+1]; anyTargetIntegers[count+1] = temp; isChanged = true; --limit; if(!isChanged){ break; 配列要素どおしの入れ替えが無くなれば終了

// テスト用プログラム public static void print(int[] anyTargetIntegers) { int limit = anyTargetIntegers.length - 1; for(int count = 0; count < limit; count++){ if(10 > anyTargetIntegers[count]){ System.out.print(" "); } System.out.print(anyTargetIntegers[count] + ", "); System.out.println(anyTargetIntegers[limit]); public class BubbleSortTest { public static void main(String[] anyArguments) int[] intArray = {47, 18, 8, 7, 2, 4, 9, 0, 72, 88, 2, 5, 9, 10}; BubbleSort.sort(intArray); } // テスト用プログラム [sakai@star 11]$ java BubbleSortTest 47, 18, 8, 7, 2, 4, 9, 0, 72, 88, 2, 5, 9, 10 18, 8, 7, 2, 4, 9, 0, 47, 72, 2, 5, 9, 10, 88 8, 7, 2, 4, 9, 0, 18, 47, 2, 5, 9, 10, 72, 88 7, 2, 4, 8, 0, 9, 18, 2, 5, 9, 10, 47, 72, 88 2, 4, 7, 0, 8, 9, 2, 5, 9, 10, 18, 47, 72, 88 2, 4, 0, 7, 8, 2, 5, 9, 9, 10, 18, 47, 72, 88 2, 0, 4, 7, 2, 5, 8, 9, 9, 10, 18, 47, 72, 88 0, 2, 4, 2, 5, 7, 8, 9, 9, 10, 18, 47, 72, 88 0, 2, 2, 4, 5, 7, 8, 9, 9, 10, 18, 47, 72, 88 [sakai@star 11]$

クイックソート 基準値を決定 10 1 8 3 15 5 32 12 6 24 基準値を決定 10 8 3 5 1 6 15 32 12 24 < 10 整列済み 基準値を決定 5 15 < 3 1 8 6 12 32 24 10 5 15 < 3 1 8 6 12 32 24 10 10 1 8 3 15 5 32 12 6 24

public final class QuickSort { public static void print(int[] anyTargetIntegers) int limit = anyTargetIntegers.length - 1; for(int count = 0; count < limit; count++){ if(10 > anyTargetIntegers[count]){ System.out.print(" "); } System.out.print(anyTargetIntegers[count] + ", "); System.out.println(anyTargetIntegers[limit]); public static void sort(int[] anyTargetIntegers) if(null == anyTargetIntegers){ throw new NullPointerException(); QuickSort.sort(anyTargetIntegers, 0, anyTargetIntegers.length -1);

そこで、候補として左端・中央・右端を選択し、実際にどれを基準値にするか? private static int getPivot(int[] anyTargetIntegers, int aStart, int anEnd) { int left = anyTargetIntegers[aStart]; int middle = anyTargetIntegers[aStart + ((anEnd - aStart)/2)]; int right = anyTargetIntegers[anEnd]; if((left < middle) && (middle < right)){ return middle; } if((left > middle) && (middle > right)){ if((left < right) && (right < middle)){ return right; if((left > right) && (right > middle)){ if((right < left) && (left < middle)){ return left; できれば、最大値や最小値を避けたい。 そこで、候補として左端・中央・右端を選択し、実際にどれを基準値にするか? このとき、3個のデータの並び(6通り)を考えて、3個のデータの中央値をとる。

private static void sort(int[] anyTargetIntegers, int aStart, int anEnd) { int range = anEnd - aStart; if(3 > range){ /* 要素数が少ないとき(要素数3以下)、別の方法でソート */ } int pivot = QuickSort.getPivot(anyTargetIntegers, aStart, anEnd); int temp = 0; int left = aStart; int right = anEnd; while(true){ /* 入れ替える要素を探します */ if(left < right){ /* 要素を入れ替え、 基準値に従って分けます */ }else{ break; QuickSort.sort(anyTargetIntegers, aStart, left -1); QuickSort.sort(anyTargetIntegers, right +1, anEnd); QuickSort.print(anyTargetIntegers); for(; left < right; left++){ if(pivot <= anyTargetIntegers[left]){ break; } for(; left < right; right--){ if(pivot >= anyTargetIntegers[right]){

if(2 == range){ /* 要素数が3の場合はバブルソート */ if(anyTargetIntegers[aStart] > anyTargetIntegers[aStart+1]){ int temp = anyTargetIntegers[aStart]; anyTargetIntegers[aStart] = anyTargetIntegers[aStart+1]; anyTargetIntegers[aStart+1] = temp; } if(anyTargetIntegers[aStart+1] > anyTargetIntegers[anEnd]){ int temp = anyTargetIntegers[aStart+1]; anyTargetIntegers[aStart+1] = anyTargetIntegers[anEnd]; anyTargetIntegers[anEnd] = temp; }else if(1 == range){ /* 要素数が2の場合は比較して入れ替え */ if(anyTargetIntegers[aStart] > anyTargetIntegers[anEnd]){ anyTargetIntegers[aStart] = anyTargetIntegers[anEnd]; QuickSort.print(anyTargetIntegers); return;

基準値が左側に含まれる場合 基準値を右へ 1つ移動 基準値が右側に含まれる場合 基準値を左へ 1つ移動 基準値がどちらにも含まれない場合 if(pivot == anyTargetIntegers[left]){ temp = anyTargetIntegers[left]; anyTargetIntegers[left] = anyTargetIntegers[right]; anyTargetIntegers[right] = anyTargetIntegers[left+1]; anyTargetIntegers[left+1] = temp; left++; }else if(pivot == anyTargetIntegers[right]){ temp = anyTargetIntegers[right]; anyTargetIntegers[right] = anyTargetIntegers[left]; anyTargetIntegers[left] = anyTargetIntegers[right-1]; anyTargetIntegers[right-1] = temp; right--; }else{ anyTargetIntegers[right] = temp; } 基準値が左側に含まれる場合 基準値を右へ 1つ移動 基準値が右側に含まれる場合 基準値を左へ 1つ移動 基準値がどちらにも含まれない場合 単純に入れ替え

[sakai@star 11]$ java QuickSortTest public class QuickSortTest { public static void main(String[] anyArguments) int[] intArray = {47, 18, 8, 7, 2, 4, 9, 0, 72, 88, 2, 5, 9, 10}; QuickSort.sort(intArray); } [sakai@star 11]$ java QuickSortTest 47, 18, 8, 7, 2, 4, 9, 0, 72, 88, 2, 5, 9, 10 Pivot = 10 9, 5, 8, 7, 2, 4, 9, 0, 2, 10, 88, 72, 18, 47 Pivot = 9 2, 5, 8, 7, 2, 4, 9, 0, 9, 10, 88, 72, 18, 47 Pivot = 2 0, 2, 2, 7, 8, 4, 9, 5, 9, 10, 88, 72, 18, 47 0, 2, 2, 7, 8, 4, 9, 5, 9, 10, 88, 72, 18, 47 Pivot = 5 0, 2, 2, 4, 5, 8, 9, 7, 9, 10, 88, 72, 18, 47 0, 2, 2, 4, 5, 8, 9, 7, 9, 10, 88, 72, 18, 47 0, 2, 2, 4, 5, 7, 8, 9, 9, 10, 88, 72, 18, 47 Pivot = 72 0, 2, 2, 4, 5, 7, 8, 9, 9, 10, 47, 18, 72, 88 0, 2, 2, 4, 5, 7, 8, 9, 9, 10, 18, 47, 72, 88 [sakai@star 11]$

ソートの計算量 n個のデータの並びは n! とおり存在する 1回の比較で並びの可能性が1/2にできる 並びの可能性が1以下にできればソート完了 そのときの比較回数をkとすれば、 すなわち Stirlingの公式から およそ n log nという計算量になる 比較を使う限りの性能上限

分割統治法(162ページ) 元の問題をサイズの小さいいくつかの部分問題に分割 個々の部分問題を何らかの方法で解決 それらの解を統合することで元の問題の解を得る

マージソート(198ページ) 手続きf(p) 問題pを半分にする それぞれの部分問題に対して次の処理 半分にした問題をマージする 部分問題の要素数が2個 小さい順に並び替える→次の処理へ 部分問題の要素数が1個 並び替える必要が無い→次の処理へ 部分問題の要素数が2個より多い 手続きfを部分問題を引数に呼ぶ 半分にした問題をマージする 部分問題列の先頭から、小さい順に取り出す

69 11 84 63 76 91 53 97 41 2 28 31 58 19 12 88 53 69 69 11 84 84 63 97 97 76 91 91 12 53 41 84 2 28 28 31 63 58 97 19 88 88 41 69 11 58 91 76 12 53 2 31 88 19 41 76 28 63 12 58 11 31 2 19 2 11 12 19 28 31 41 53 58 63 69 76 84 88 91 97

マージソート (逐次処理, 201ページ) データの分割にかかる時間(2要素に分解) n/2 ソートにかかる時間(段数log2n, データ数n)   n log2n ステップ数は n/2 + n log2n つまり O(n log2n)   クイックソートと並ぶオーダーで処理ができる

マージソート (並列処理) データの分割にかかる時間(2要素に分解) log2n - 1 ソートにかかる時間 2n - 1 ステップ数は (log2n + 2n – 2) つまり O(n)    例ではn=16なので34ステップで終了

69 11 84 63 76 91 53 97 41 2 28 31 58 19 12 88 53 69 69 11 84 84 63 97 97 76 91 91 12 53 41 84 2 28 28 31 63 58 97 19 88 88 41 69 11 58 91 76 12 53 2 31 88 19 41 76 28 63 12 58 11 31 2 19 2 11 12 19 28 31 41 53 58 63 69 76 84 88 91 97

パイプラインマージソート データの分割にかかる時間(図には書いてない) log2n - 1 最初のデータがソートされる時間 log2n 引き続くn-1個のデータがソートされる時間     n-1 ステップ数は (2 log2n + n-2) つまりO(n)である   例では、n=16 なので22ステップで終了