【Python】ソートの復讐1:バブルソート
ソートの復習用の記事です。
最初なので実装も簡単なバブルソートについて書きます。
ひとまず結論
- 最悪・平均計算量: O(n2)
- Pythonでの実装例
def bubble_sort(input_arr): len_arr = len(input_arr) update_flag = True while update_flag: update_flag = False for i in range(1,len_arr): if input_arr[i-1] > input_arr[i]: input_arr[i-1], input_arr[i] = input_arr[i], input_arr[i-1] update_flag = True return input_arr
バブルソート
- 入力配列を隣接要素の比較・入れ替え操作でソートするアルゴリズム
- 名前の由来:比較・入れ替え操作により大きい/小さい要素が浮かび上がるようにみえるから(バブル:泡のように)
- 利点:アルゴリズムが単純 → 実装が容易
- 欠点:平均計算量が大きい(要素数がNの場合、最大でN2の操作が必要)
- アルゴリズムの内容:手順(小さい順に並べる場合)
- 入力配列をin、入力配列サイズをNとする
- i = 0とする
- in[i]とin[i+1]の値を比較
- もし、in[i] > in[i+1]ならば、値の入れ替えを実施
- iをインクリメント
- i < N ならば操作2に戻る
- 操作2-5で、入れ替えを行った場合は操作1に戻る
- 終了
- 入力配列をin、入力配列サイズをNとする
- N=5の配列に対して、バブルソートを実行すると以下図のような処理の流れになる
Pythonでの処理速度
- 計測環境
- 下記コードを評価に使用
- 配列サイズNを変化させて評価
import numpy as np import time def bubble_sort(input_arr): len_arr = len(input_arr) update_flag = True while update_flag: update_flag = False for i in range(1,len_arr): if input_arr[i-1] > input_arr[i]: input_arr[i-1], input_arr[i] = input_arr[i], input_arr[i-1] update_flag = True return input_arr N=10 input_arr = np.random.rand(N) st = time.time() result_arr = bubble_sort(input_arr) elapsed = time.time() - st print("Elapsed time[sec] : ", elapsed)
評価結果
配列サイズ | 100 | 1000 | 10000 |
---|---|---|---|
処理時間[sec] | 0.009 | 1.153 | 48.133 |
平均計算量が配列サイズの2乗に比例するため、配列サイズの増加量以上に処理時間が伸びている。
サイズ100→1000のときは、サイズが10倍になって処理時間が100倍になっており計算量の増加にあった処理時間の増加である。
ただし、入力配列がソートされた状態に近いほど走査回数は少なくなるため速く完了する。
まとめ
今回は、実装が簡単なバブルソートを復習しました。
関数実装は簡単ですが、評価結果からもわかるように、配列サイズの増加に対する処理時間の増加は恐ろしいものです。
配列サイズが大きいときは、別のアルゴリズムを選択するべきです。
配列サイズがちいさいときには、便利なソートアルゴリズムではないでしょうか?
以上、ありがとうございました。