大岩 元 慶応大学環境情報学部 ohiwa@sfc.keio.ac.jp 再帰 データ構造とプログラミング(8) 大岩 元 慶応大学環境情報学部 ohiwa@sfc.keio.ac.jp.

Slides:



Advertisements
Similar presentations
4.3 マージソート.
Advertisements

離散システム特論 整列(sorting)アルゴリズム 2.
4.ソート 4-1.ソート問題について 4-2.簡単なソートアルゴリズム 4-3.高度なソートアルゴリズム
アルゴリズムとデータ構造 2012年6月27日
第12回 ソート(3): シェルソート、クイックソート
高速ソートと 安定結婚問題 平成24年12月14日.
アルゴリズムとデータ構造 第8回 ソート(3).
第10回 整列 ~ バブルソート,挿入ソート,選択ソート~
第11回 整列 ~ シェルソート,クイックソート ~
アルゴリズムとデータ構造 2013年6月18日
アルゴリズムとデータ構造1 2005年7月8日
アルゴリズムとデータ構造 2010年7月5日
2009/10/30 整列アルゴリズム (2) 第5講: 平成21年10月30日 (金) 4限 E252教室 コンピュータアルゴリズム.
4-3:高度なソートアルゴリズム① (分割統治法にもとづくソート)
第9回 並び替えアルゴリズム ~さまざまなアルゴリズムを比較しよう~.
4.整列のアルゴリズム.
プログラミング論 I 関数の再帰呼び出し
第10回 ソート(1):単純なソートアルゴリズム
アルゴリズムとデータ構造 2012年6月14日
アルゴリズムとデータ構造 2011年6月13日
データ構造とアルゴリズム 分割統治 ~ マージソート~.
データ構造と アルゴリズム 第八回 知能情報学部 新田直也.
大岩 元 慶応大学環境情報学部 二分木 データ構造とプログラミング(10) 大岩 元 慶応大学環境情報学部
アルゴリズムとデータ構造 2011年6月14日
第11回 整列 ~ シェルソート,クイックソート ~
二分探索木によるサーチ.
アルゴリズムとデータ構造 2012年6月28日
アルゴリズムとデータ構造 2011年6月27日
2009/11/6 整列アルゴリズムの復習 第6講: 平成21年11月6日 (金) 4限 E252教室 コンピュータアルゴリズム.
関数の定義.
アルゴリズムとデータ構造1 2006年6月16日
アルゴリズムとデータ構造1 2005年7月15日
ソートアルゴリズムの種類 選択ソート (selection sort) バブルソート (bubble sort)
プログラミング2 関数の再帰呼び出し
2011/06/21-24 情報知能学科「アルゴリズムとデータ構造」 担当:白井英俊
情報工学概論 (アルゴリズムとデータ構造)
二分探索木における要素削除 データ構造とプログラミング(10)
アルゴリズムとデータ構造1 2005年7月1日
クイックソート.
Cプログラミング演習 第10回 二分探索木.
アルゴリズムとプログラミング (Algorithms and Programming)
先進的計算基盤システムシンポジウム SACSIS2007併設企画 マルチコアプログラミングコンテスト 「Cellスピードチャレンジ2007」
復習+α JBuilderの使い方を思い出す。 配列とGUI 再帰とマージソート 木と二分木の探索
プログラミング 4 整列アルゴリズム.
アルゴリズムとデータ構造1 2005年6月24日
アルゴリズムとデータ構造 2010年6月21日
大岩 元 慶応大学環境情報学部 再帰 データ構造とプログラミング(8) 大岩 元 慶応大学環境情報学部
2009/10/23 整列アルゴリズム (1) 第4講: 平成21年10月23日 (金) 4限 E252教室 コンピュータアルゴリズム.
アルゴリズムとデータ構造 2010年7月26日
オブジェクト指向 プログラミング 第六回 知能情報学部 新田直也.
再帰的手続き.
アルゴリズムとデータ構造1 2006年7月11日
アルゴリズムとデータ構造 2011年6月23日
プログラミング演習Ⅲ- Sorting Quick Sort and Merge Sort
データ構造とアルゴリズム (第5回) 静岡大学工学部 安藤和敏
オブジェクト指向 プログラミング 第六回 知能情報学部 新田直也.
アルゴリズムとデータ構造 2012年7月2日
アルゴリズムとデータ構造 2012年6月11日
アルゴリズムとプログラミング (Algorithms and Programming)
アルゴリズムとデータ構造1 2008年7月24日
アルゴリズムとデータ構造 2011年6月28日
アルゴリズムとデータ構造 2013年7月1日
計算機プログラミングI 第4回 2002年10月31日(木) 問題解決とアルゴリズム クラスメソッドと手続きの抽象化 最大公約数
アルゴリズムとデータ構造 2013年7月2日
ソートのプログラムの流れ 配列の中身を小さい順に並び替える a[1],a[2],…a[n]の値を順に出力する
アルゴリズムとデータ構造 2012年6月25日
オブジェクト指向 プログラミング 第四回 知能情報学部 新田直也.
プログラミング2 関数の再帰呼び出し
オブジェクト指向 プログラミング 第六回 知能情報学部 新田直也.
プログラミング論 バイナリーサーチ 1.
Presentation transcript:

大岩 元 慶応大学環境情報学部 ohiwa@sfc.keio.ac.jp 再帰 データ構造とプログラミング(8) 大岩 元 慶応大学環境情報学部 ohiwa@sfc.keio.ac.jp

マージソート ソート済みの2つの配列をマージして1つのソート済み配列にする 未ソートの配列を2つの未ソート配列に分解する作業を再帰的に繰り返すと、最後は1つの要素から成る配列(ソート済)となる 2つに分解した再帰から帰ってきた所で、マージすれば、ソート済みとなる 作業用配列を必要とするが、O(n*log(n))で処理できる

マージソートのプログラム public void mergeSort(){ double[ ] workSpace = new double[nElems]: recMergeSort(workspace, 0, dElems-1); } private void recMergeSort( double workspace, int lowerBound, int upperBound){ { if (lowerBound == upperBound) return else {int mid = (lowerBound + upperBound)/2: //中間点を見つける recMergesort( workspace, lowerBound, mid); //下半分をソートする recMergeSort( workspace, mid+1, upperBound): //上半分をソートする merge(work]space, lowerBound, mid+1, upperBound);//マージする

マージのプログラム private void merge( double[ ] workSpace, int lowPtr, int highPtr, int upperBound){ int j = 0; int lowerBound = lowPtr; int mid = highPter-1; int n = upperBound – LowerBound + 1; while( lowPtr <= mid && highPtr <= upperBound) if( theArray[lowPtr] < theArray[highPtr]) workSpace[j++] = theArray[lowPtr++] else workSpace[j++] = theArray[highPtr++]; while( lowPtr <= mid) workSpace[j++] = theArray[lowPtr++]; while( highPtr <= upperBound) workSpace[j++] = theArray[highPtr++]; for (j = 0; j < n; j++) theArray[loweBound + j] = workSpace[j];

マージソートの効率(2**n個の時) コピー回数は、配列から作業配列へと、その反対へ、それぞれ n*log(n) 回となる 各マージで(m個の要素)、最大比較回数は m-1、最小比較回数はm/2 コピーもマージも、O(n*log(n))

再帰の自己関理 再帰呼び出しが行なわれると、引き数と帰り先がスタックにプッシュされる 呼ばれたメソッドはスタックを見て、引き数を得る メソッドが終ると、スタックから帰り先をポップし、そこに戻る。引数はポップして捨てる

クイックソート ピボットを配列の中から任意(例題では右端)に選ぶ ピボットより大きな要素を右に、小さな要素を左に入れる(分割 partition) 右側と左側をそれぞれ、再帰的に呼び出す 分割が左右均等にできれば、計算時間はO(n*log(n)) 分割が常に片寄ると、O(n*n)になってしまう

クイックソートの主要部 public void recQuickSort( int left, int right){ if (right-left <= 0) return; else{ double piivot = theArray[ right]; int partition = partitionIt( left, right, pivot); recQuickSort( left, partition-1); recQuickSort( partition+1, right); }

分割(partition) public int partitionIt(int left, int right, double pivot){ int leftPtr = left – 1; int rithPtr = right; while(true){ while( theArray[++leftPtr] < pivot) //NOP while( rightPtr > 0 && theArray[--Ptr] > pivot) //NOP if (leftPtr >= rightPtr) break; else swap( leftPtr, rightPtr) } swap( leftPtr, right); return leftPtr;