バブルソート,バケツソート,クイックソート

Slides:



Advertisements
Similar presentations
アルゴリズムイントロダクション第2章 主にソートに関して
Advertisements

第12回 ソート(3): シェルソート、クイックソート
アルゴリズムとデータ構造 第8回 ソート(3).
第10回 整列 ~ バブルソート,挿入ソート,選択ソート~
近似アルゴリズム 第10章 終了時刻最小化スケジューリング
第11回 整列 ~ シェルソート,クイックソート ~
データ構造とアルゴリズム論 第5章 整列(ソート)のアルゴリズム
第11回 整列 ~ バケットソート,基数ソート,ヒープソート~
配列(2) 第10回[平成15年6月26日(木)]:PN03-10.ppt 今日の内容 1 素数を求める(教科書の例):復習
データ構造とアルゴリズム 第10回 mallocとfree
プログラミング論 I 行列の演算
基礎プログラミングおよび演習 第9回
プログラミング基礎I(再) 山元進.
問題提起その 1 一文字ずつ文字(数字)を読み込み、それぞれの文字が何回入力されたかを数えて出力するプログラム。
プログラミング演習(2組) 第12回
プログラミング論 I 関数の再帰呼び出し
第10回 ソート(1):単純なソートアルゴリズム
 Combinations(2)        古川 勇輔.
第6章 2重ループ&配列 2重ループと配列をやります.
データ構造とアルゴリズム 分割統治 ~ マージソート~.
岩井 儀雄 コンピュータ基礎演習  ー探索、整列ー 岩井 儀雄
プログラミング論 II 電卓,逆ポーランド記法電卓
非線形方程式の近似解 (2分法,はさみうち法,Newton-Raphson法)
データ構造とアルゴリズム論 第2章 配列(構造)を使った処理
ML 演習 第 7 回 新井淳也、中村宇佑、前田俊行 2011/05/31.
データ構造と アルゴリズム 第十一回 理工学部 情報システム工学科 新田直也.
第11回 整列 ~ シェルソート,クイックソート ~
精密工学科プログラミング基礎Ⅱ 第3回資料 今回の授業で習得してほしいこと: 2次元配列の使い方 (前回の1次元配列の復習もします.)
プログラミング基礎a 第8回 プログラムの設計 アルゴリズムとデータ構造
二分探索木によるサーチ.
第7回 条件による繰り返し.
プログラミング論 関数ポインタ と 応用(qsort)
ちょっとした練習問題① 配列iroを['R', 'W', 'R', 'R', 'W' , 'W' , 'W']を宣言して、「W」のときの配列の番号をprintfで表示するようなプログラムを記述しなさい。
プログラミング2 関数
定兼邦彦 今井浩 東京大学理学系研究科 情報科学専攻
プログラミング入門 電卓を作ろう・パートIV!!.
アルゴリズムとデータ構造1 2006年6月16日
アルゴリズムとデータ構造1 2005年7月15日
ソートアルゴリズムの種類 選択ソート (selection sort) バブルソート (bubble sort)
プログラミング2 関数の再帰呼び出し
前回の練習問題.
講義では、Cプログラミングの基本を学び 演習では、やや実践的なプログラミングを通して学ぶ
第7回 条件による繰り返し.
復習 前回の関数のまとめ(1) 関数はmain()関数または他の関数から呼び出されて実行される.
わんくま同盟茶藝部顧問 Microsoft MVP for VC episthmh
アルゴリズムとデータ構造 第3章 ヒープ 6月10日分
大岩 元 慶応大学環境情報学部 再帰 データ構造とプログラミング(8) 大岩 元 慶応大学環境情報学部
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回 プログラムの設計 アルゴリズムとデータ構造
プログラミング 4 整列アルゴリズム.
2009/10/23 整列アルゴリズム (1) 第4講: 平成21年10月23日 (金) 4限 E252教室 コンピュータアルゴリズム.
データ構造とアルゴリズム論 第5章 整列(ソート)のアルゴリズム
アルゴリズムとデータ構造1 2006年7月11日
アルゴリズムとプログラミング (Algorithms and Programming)
アルゴリズムとデータ構造 --- 理論編 --- 山本 真基
ハフマン符号長の効率的な求め方.
復習 Cにおけるループからの脱出と制御 break ループを強制終了する.if文と組み合わせて利用するのが一般的. continue
アルゴリズムとプログラミング (Algorithms and Programming)
ソートのプログラムの流れ 配列の中身を小さい順に並び替える a[1],a[2],…a[n]の値を順に出力する
情報処理Ⅱ 2006年11月24日(金).
ヒープソート.
2008年6月5日 非線形方程式の近似解 2分法,はさみうち法,Newton-Raphson法)
プログラミング2 関数の再帰呼び出し
参考:大きい要素の処理.
プログラミング入門2 第5回 配列 変数宣言、初期化について
プログラミング入門2 第3回 条件分岐(2) 繰り返し文 篠埜 功.
プログラミング演習I 補講用課題
プログラミング論 バイナリーサーチ 1.
Presentation transcript:

バブルソート,バケツソート,クイックソート プログラミング論 バブルソート,バケツソート,クイックソート http://www.ns.kogakuin.ac.jp/~ct13140/Prog/

概要 バブルソート,バケツソート 簡単 クイックソート 難しいが重要.

数字を降順/昇順に並び替える アルゴリズム. バブルソート,バケツソート,クイックソート ソート SORT 数字を降順/昇順に並び替える アルゴリズム. バブルソート,バケツソート,クイックソート

ソート 数を並び替える. 4,8,0,5,7 ↓ソート 0,4,5,7,8

ソート 例 int a[10] に10個の整数が格納されているとする. これを小さい順に並び替えて表示する.

ソートアルゴリズム バブルソート,バケツソート,クイックソートを紹介する. 以下,数値を昇順に並び替えるとする. 降順への並び替えも基本は同じ.

バブルソート 「隣接する2要素の大小を比較し,正しくない状態だったらその2要素を交換する」ことを繰り返す. O(n2)であり,一般には遅いソートアルゴリズムと認識されている. 実装(プログラムの作成)はとても楽 7

バブルソートの概要 ソート結果はa[0]≦a[1]のはずである. 同様に a[1]≦a[2]のはず,a[2]≦a[3]のはず, 「a[i]≦a[i+1]」が成り立つはず. 8

バブルソートの概要 「もし,a[i]>a[i+1]であったら,この2個を交換する」 注意:配列長が10なら, iは0~9では無くて,iは0~8. i=9の時,a[9]とa[10]の処理になる. 上記「『もし逆なら交換する』を全てのiについて行う」を何回も行うと,ソートができる. 9

バブルソートの例 「9,3,5,2」をソートする. 9 3 5 2 比較 順序が逆なので,交換する. 3 9 5 2 10

バブルソートの例 「9,3,5,2」をソートする. 3 9 5 2 3 5 9 2 3 5 2 9 「調査&交換」を 左から右に向かって 繰り返す. これ1回を「走査」と 呼ぶこととする. 比較&交換する. 3 5 9 2 比較&交換する. 3 5 2 9 ←初期状態より,ソートが進んだ. これで,「a[i]とa[i+1]を比較し,逆なら交換する」 を左から右まで「全てのa[i]とa[i+1]の組」に行った. 11

バブルソートの例 「9,3,5,2」をソートする. 3 5 2 9 3 5 2 9 3 2 5 9 3 2 5 9 もう1回,左から右に 「調査&交換」繰り返した. 3 5 2 9 比較&交換しない. 3 5 2 9 比較&交換する. 3 2 5 9 比較&交換しない. 3 2 5 9 12

バブルソートの例 「9,3,5,2」をソートする. ←ソート完了 3 2 5 9 2 3 5 9 2 3 5 9 2 3 5 9 もう1回,左から右に 「調査&交換」繰り返した. 3 2 5 9 比較&交換する. 2 3 5 9 ←ソート完了 比較&交換しない. 2 3 5 9 比較&交換しない. 2 3 5 9 13

バブルソート 「『a[i]とa[i+1]を比較して交換』を 左から右に繰り返す」 ことを繰り返せば,ソートが完了する. さて,何回繰り返せば完了するかを考える. 14

バブルソートの比較回数 「比較&交換」を左から右に1回走査する. すると,必ず最大値が一番右に移動する.よって,一番右は決定! 9 3 5 2 「比較&交換」を左から右に1回走査する. すると,必ず最大値が一番右に移動する.よって,一番右は決定! それ以外は,まだ決定していない. 3 9 5 2 3 5 9 2 3 5 2 9 15

バブルソートの比較回数 「比較&交換」を左から右.2走査目. すると,右の2個が決定する. それ以外は,まだ完了していない. 3 5 2 9 実は,3回目の「比較&交換」は不要 16

バブルソートの比較回数 「比較&交換」を左から右.3走査目. すると,右の3個が決定する. 実は,一番左も決定している. よってこれで終了. 2 5 9 「比較&交換」を左から右.3走査目. すると,右の3個が決定する. 実は,一番左も決定している. よってこれで終了. 2 3 5 9 3 2 5 9 3 2 5 9 実は,2,3回目の「比較&交換」は不要 17

バブルソートの比較回数 a[100](a[0]~a[99])のバブルソートの例 1走査目.以下が必要. a[0]とa[1]の比較,a[1]とa[2]の比較, (略) a[98]とa[99]の比較. よって,99回比較する. 注意:100回ではない. 18

バブルソートの比較回数 2走査目.以下が必要. a[0]とa[1]の比較,a[1]とa[2]の比較, (略) a[97]とa[98]の比較. よって,98回比較する. 1走査目より1回減っている. 最後の1個は既に決定しているので. 19

バブルソートの比較回数 3走査目.以下が必要. a[0]とa[1]の比較,a[1]とa[2]の比較, (略) a[96]とa[97]の比較. よって,97回比較する. 2走査目よりさらに1回減っている. 最後の2個は既に決定しているので. 20

バブルソートの比較回数 n走査目.以下が必要. a[0]とa[1]の比較,a[1]とa[2]の比較, (略) a[99-n]とa[100-n]の比較. よって,100-n回比較する. 最後のn-1個は既に決定しているので. 21

バブルソートの比較回数 99走査目.以下が必要. a[0]とa[1]の比較. よって,1回比較する. 右の98個は既に決定しているので. 22

for(i=0; i<SIZE-1; i++){ for(j=0; j<SIZE-1-i; j++){ if( data[j+1] < data[j] ){ tmp = data[j+1]; data[j+1] = data[j]; data[j] = tmp; } 23

バケツソート O(n)でソートできるアルゴリズム. 最速のアルゴリズムと言えるが, 大量のメモリが必要, データの範囲(最小値,最大値)が既知であることが必要. 値の範囲が大きいほど大量のメモリが必要. 同じ値が2個以上あるとやりづらい. 浮動小数点には使いづらい. 24

バケツソートの例 a[5]をソートする.各値は,0~9の整数であることが分かっているとする. 以下のデータをソートする例を考える. 9 3 2 25

バケツソートの例 値の範囲が0~9の10種類なので, 「バケツ0」~「バケツ9」の 10個のバケツを用意する. 9 3 5 2 バケツの中 バケツ 0 空 バケツ 1 空 a[0] a[1] a[2] a[3] a[4] バケツ 2 空 バケツ 3 空 9 3 5 2 バケツ 4 空 バケツ 5 空 バケツ 6 空 バケツ 7 空 バケツ 8 空 バケツ 9 空 26

バケツソートの例 9 3 5 2 バケツの中 バケツ 0 空 バケツ 1 空 バケツ 2 空 バケツ 3 空 バケツ 4 空 バケツ 5 空 a[0] a[1] a[2] a[3] a[4] バケツ 2 空 バケツ 3 空 9 3 5 2 バケツ 4 空 バケツ 5 空 バケツ 6 空 バケツ 7 空 a[0]に着目. 値は"9"なので, バケツ9に入れる. バケツ 8 空 バケツ 9 1個 27

バケツソートの例 9 3 5 2 バケツの中 バケツ 0 空 バケツ 1 空 バケツ 2 空 バケツ 3 1個 バケツ 4 空 バケツ 5 a[0] a[1] a[2] a[3] a[4] バケツ 2 空 バケツ 3 1個 9 3 5 2 バケツ 4 空 バケツ 5 空 バケツ 6 空 バケツ 7 空 a[1]に着目. 値は"3"なので, バケツ3に入れる. バケツ 8 空 バケツ 9 1個 28

バケツソートの例 9 3 5 2 バケツの中 バケツ 0 空 バケツ 1 空 バケツ 2 空 バケツ 3 1個 バケツ 4 空 バケツ 5 a[0] a[1] a[2] a[3] a[4] バケツ 2 空 バケツ 3 1個 9 3 5 2 バケツ 4 空 バケツ 5 1個 バケツ 6 空 バケツ 7 空 a[2]に着目. 値は"5"なので, バケツ5に入れる. バケツ 8 空 バケツ 9 1個 29

バケツソートの例 9 3 5 2 バケツの中 バケツ 0 空 バケツ 1 空 バケツ 2 1個 バケツ 3 1個 バケツ 4 空 バケツ 5 a[0] a[1] a[2] a[3] a[4] バケツ 2 1個 バケツ 3 1個 9 3 5 2 バケツ 4 空 バケツ 5 1個 バケツ 6 空 バケツ 7 空 a[3]に着目. 値は"2"なので, バケツ2に入れる. バケツ 8 空 バケツ 9 1個 30

バケツソートの例 9 3 5 2 バケツの中 バケツ 0 1個 バケツ 1 空 バケツ 2 1個 バケツ 3 1個 バケツ 4 空 a[0] a[1] a[2] a[3] a[4] バケツ 2 1個 バケツ 3 1個 9 3 5 2 バケツ 4 空 バケツ 5 1個 バケツ 6 空 バケツ 7 空 a[4]に着目. 値は"0"なので, バケツ0に入れる. バケツ 8 空 バケツ 9 1個 31

バケツソートの例 各値の登場回数の表が完成した. この表を上から下に読んでいけば ソート終了. 0,2,3,5,9 バケツの中 バケツ 0 1個 バケツ 1 空 バケツ 2 1個 バケツ 3 1個 バケツ 4 空 バケツ 5 1個 バケツ 6 空 バケツ 7 空 バケツ 8 空 バケツ 9 1個 32

バケツソート 以下の手順でプログラミング可能 [1]バケツ0~バケツ9を作成する.  各バケツには,「登場回数」を記録するので,intで長さ10の配列を宣言すればよい. [2]全バケツの値を0個として初期化する.  バケツの長さ(10)でfor分を使う. [3]全データをそれぞれのバケツに振り分けていく.データの長さ(5)でfor分を使う.

バケツソート [4]全バケツに入ったデータを上から読んでいく.バケツの長さ(10)でfor分を使う. for(i=0; i<10; i++){ for(j=0; j<bucket[i]; j++){ ... }

#include <stdio.h> #define DATA_NUM 5 #define VALUE_MAX 100 void main(){ int data[DATA_NUM], bucket[VALUE_MAX], i, v, cnt, score; data[0]=72; data[1]=46; data[2]=50; data[3]=46; data[4]=22; for(v=0; v<VALUE_MAX; v++){ bucket[ v ] = 0; } for(i=0; i<DATA_NUM; i++){ score = data[i]; bucket[score] ++; for(i=0; i<bucket[v]; i++){ printf("%d\n“, v); [1]バケツ0~バケツ9を作成する [2]全バケツの値を0個として初期化する [3]全データを それぞれのバケツに振り分けていく [4]全バケツに入ったデータを 上から読んでいく

#include <stdio.h> #define DATA_NUM 5 #define VALUE_MAX 100 void main(){ int data[DATA_NUM], bucket[VALUE_MAX], i, v, cnt, score; data[0]=72; data[1]=46; data[2]=50; data[3]=46; data[4]=22; for(v=0; v<VALUE_MAX; v++){ bucket[ v ] = 0; } for(i=0; i<DATA_NUM; i++){ score = data[i]; bucket[score] ++; cnt=0; for(i=0; i<bucket[v]; i++){ data[cnt] = v; cnt ++; printf("%d\n", data[i]); [1]バケツ0~バケツ9を作成する [2]全バケツの値を0個として初期化する [3]全データを それぞれのバケツに振り分けていく [4]全バケツに入ったデータを 上から読んでいく

バケツソート データの取り得る範囲の数だけバケツが必要. 例えば,多くの場合int型は32bitだが, データの範囲が2^32通りある場合は,43億個のバケツが必要. バケツ1個が1バイトとしても,4GBの記憶領域が必要. 可変長文字列のソートなど,バケツを用意しようが無い場合は適応不可能. バケツが無限通りになってしまう. 37

クイックソート 通常,O(nlog(n))でソート可能なアルゴリズム. かなり高速で,制限も無いため非常によく使われるアルゴリズム. ただし,不安定なソートアルゴリズムである. つまり,同一の値が2個以上あったとき, それらの順位は保証されない.(どうなるか分からない) 38

クイックソート 配列の中から,キーとなる枢軸(pivot)を決定する. 枢軸の決定方法は後述. 枢軸は,データの中間値が好ましい. 39

クイックソート 左半分が枢軸未満,右半分が枢軸以上となるようにデータ交換を繰り返す. 具体的には,左端からデータを調査していき枢軸以上の値を探す.右端から枢軸未満の値を探す.そして,この2個を交換する. 左に枢軸以上があってはならない.右も同様. 左からの走査と,右からの走査が出会ったら,走査1回終わり. 必ずしも,左半分のデータの個数と,右半分のデータの個数が等しくない. 40

クイックソート 1回捜査をすると,「左半分が枢軸未満,右半分が枢軸以上」となっている. 左グループと右グループに分割し, それぞれをそれぞれの枢軸で再度走査し, それぞれをまた分割する. 分割グループ内の数値が全部同じになるまで分割を繰り返す.(グループの大きさが1になった場合も,「数値が全部同じ」) 41

クイックソートの例 3 1 4 1 5 9 2 6 5 3 枢軸を決める."3"とする.枢軸決定方法は後述. 左から枢軸以上の値を,右から枢軸未満の値を探す. 3 1 4 1 5 9 2 6 5 3 両者を交換する 2 1 4 1 5 9 3 6 5 3 左右からの検索の続きを行う. 2 1 4 1 5 9 3 6 5 3 両者を交換する 2 1 1 4 5 9 3 6 5 3 左右からの検索の続きを行う. 2 1 1 4 5 9 3 6 5 3 出会ってしまったので走査終了. 「左半分枢軸未満, 右半分枢軸以上」 が達成された. 2 1 1 4 5 9 3 6 5 3 42

クイックソートの例 2 1 1 4 5 9 3 6 5 3 分割する 2 1 1 4 5 9 3 6 5 3 枢軸2で分割 枢軸5で分割 1 終了 終了 枢軸4で分割 枢軸9で分割 3 3 4 5 6 5 9 3 3 4 5 6 5 9 枢軸6 終了 終了 終了 5 5 6 終了 終了 43

枢軸の決定方法 枢軸未満と枢軸以上に分割するため, 片方のグループの要素数が0個となってはならない. 例えば,「異なる数字を左から2個探し,その大きい方を枢軸とする」とすれば,「枢軸未満」「枢軸以上」ともに最低1個存在することになる. 異なる数がなければ(全部同じなら)分割不要. 失敗例 4 5 9 一番左の4を枢軸として採用 枢軸未満 枢軸以上 分割できなかった. 4 5 9 44

好ましい枢軸の決定方法 ちょうど,2分割されることが好ましい. そのためには,データの中間値に近い値を枢軸とすると良い. 例えば,ランダムに選んだ3個の中間値を採用. 好ましい例 45

好ましい枢軸の決定方法 分割に偏りがあると,計算時間が長くなる. 好ましくない例 46

好ましい枢軸の決定方法 はじめからソートされている配列をソートしようとすると,このような現象が発生する. 1 2 3 4 5 6 7 1 2 3 4 5 6 7 枢軸=1 1 2 3 4 5 6 7 枢軸=2 1 2 3 4 5 6 7 枢軸=3 2 3 4 5 6 7 枢軸=4 3 4 5 6 7 4 5 6 7 47

クイックソート 「枢軸でグループを分割」という処理を行い,2個のグループを作る. そして,両グループを再度「枢軸で分割」を行う. そして,再度「枢軸で分割」を行う... 通常,(C言語などでは)再帰により実装する. 48

補足 通常のプログラミング言語では,ソートや検索のような基本的な機能は標準で提供されている. ソートの場合 検索では, C言語では,qsort()関数がある. Java,Ruby,Perlなどにもある.RDBMSにソート機能が用意されている. 検索では, Java,Ruby,Perlなどには,Hashがある. Hashは,O(1)で検索できる手法. 49

課題 4個の数字 12,7,1,9をバブルソートで並び変えたとき,各数の推移を記せ.

課題 int a[100] に整数が100個入っている.負の数も含まれる. (い) a[0]~a[99] の合計を求めるプログラムを作成せよ (ろ) a[X]~a[Y] の合計を求めるプログラムを作成せよ. (は) a[X]~a[Y] の合計が最大になるのは,XとYがいくつの場合か求めるプログラムを作成せよ.負の数も含まれるため,範囲が広いほど合計が大きくなるわけではない. オーダーはいくつか? (に) a[] の中に 0 が何個あるか数えるプログラムを作成せよ.