Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
挿入ソート
Susumu Yata
@s5yata
挿入ソートとは
K 個目までの要素が整列済みのとき
整列状態が維持されるように
K + 1 個目の要素を挿入する
初期状態 K = 0 として
すべての要素を挿入するまで
上記の操作を繰り返す
2014年1月18日

挿入ソート

2
挿入ソートの実行例
• 入力データ列(N = 5)
– 初期状態

59

13

37

5

79

59

13

37

5

79

13

59

37

5

79

13

37

59

5

79

5

13

37

5...
挿入ソートの実装例
void insertion_sort(int *data, size_t N) {
for (size_t i = 1; i < N; ++i) {
int value = data[i];
size_t j = i;
f...
番兵による効率化
• if (value < data[0])
– すべての要素を後ろにずらす
– ループ条件から “value < data[j – 1]” がなくなる

• else
– data[0] が番兵に挿入位置を探す
– ループ条...
挿入ソートの実装例(番兵あり)
void sort_1(int *data, size_t N) {
for (size_t i = 1; i < N; ++i) {
int value = data[i];
size_t j = i;
if ...
挿入ソートの特徴
• 時間計算量
– 要素数を N として O(N2)
• N が大きいときは危険

– 入力データ列が整列済みであれば O(N)
• これを期待して使うのは危険

• 使いどころ
– N が小さければ高速
• クイックソートの...
クイックソートとの連携
• クイックソートで分割する
– 十分に小さくなれば挿入ソートで整列する
クイックソート
クイックソート
挿入ソート

2014年1月18日

挿入ソート

クイックソート
挿入ソート

挿入ソート

挿入ソート

8
部分ソートとは
データ列の先頭 M 個の要素が
上位 M 個の要素を
整列した結果となるように並べ替える

それ以外の要素の順序は問わない

2014年1月18日

挿入ソート

9
挿入ソートによる部分ソート
• 手順
– 先頭 M 個の要素を整列する
– M + 1 個目から N 個目は以下のように操作する
• M 個目の要素以上なら何もしない
• そうでなければ整列状態が維持されるように挿入する

• 時間計算量
– ...
部分ソートの実行例
• 入力データ列(N = 7)
– 初期状態

79

13

53

37

97

29

5

13

53

79

37

97

29

5

13

37

53

79

97

29

5

13

37
...
部分ソートの実装例
void partial_sort(int *data, size_t N, size_t M) {
insertion_sort(data, M);
for (size_t i = M; i < N; ++i) {
int...
番兵による効率化(再掲)
• if (value < data[0])
– すべての要素を後ろにずらす
– ループ条件から “value < data[j – 1]” がなくなる

• else
– data[0] が番兵に挿入位置を探す
– ...
順位指定による部分ソート
• 順位指定とは
– 上位 M 個の代わりに上位 M 位までを整列する

• 実装方法
– 上位 M 位に含まれる要素の数を維持する
– 面倒なので詳細は省略

• 時間計算量
– O(M・N)
2014年1月18日
...
おわりに
• 使いどころについて
– 小規模なデータ列に強い

• 連携について
– マージソートの初期段階にも使える

• 部分ソートについて
– アイデアはほかの整列アルゴリズムでも使える
– ヒープソートの方が大きな M に対応できる
2...
Upcoming SlideShare
Loading in …5
×

挿入ソート

2,364 views

Published on

挿入ソートの概要と応用に実装方法

Published in: Technology
  • Be the first to comment

  • Be the first to like this

挿入ソート

  1. 1. 挿入ソート Susumu Yata @s5yata
  2. 2. 挿入ソートとは K 個目までの要素が整列済みのとき 整列状態が維持されるように K + 1 個目の要素を挿入する 初期状態 K = 0 として すべての要素を挿入するまで 上記の操作を繰り返す 2014年1月18日 挿入ソート 2
  3. 3. 挿入ソートの実行例 • 入力データ列(N = 5) – 初期状態 59 13 37 5 79 59 13 37 5 79 13 59 37 5 79 13 37 59 5 79 5 13 37 59 79 5 13 37 59 79 • 整列手順 – 59 を挿入 – 13 を挿入 – 37 を挿入 – 5 を挿入 – 79 を挿入 – 完了 2014年1月18日 挿入ソート 3
  4. 4. 挿入ソートの実装例 void insertion_sort(int *data, size_t N) { for (size_t i = 1; i < N; ++i) { int value = data[i]; size_t j = i; for ( ; (j > 0) && (value < data[j – 1]); --j) data[j] = data[j – 1]; data[j] = value; } } 2014年1月18日 挿入ソート 4
  5. 5. 番兵による効率化 • if (value < data[0]) – すべての要素を後ろにずらす – ループ条件から “value < data[j – 1]” がなくなる • else – data[0] が番兵に挿入位置を探す – ループ条件から “j > 0” がなくなる • 参考資料 – STL の実装(/usr/include/c++/bits/stl_algo.h) 2014年1月18日 挿入ソート 5
  6. 6. 挿入ソートの実装例(番兵あり) void sort_1(int *data, size_t N) { for (size_t i = 1; i < N; ++i) { int value = data[i]; size_t j = i; if (value < data[0]) { for ( ; j > 0; --j) // ループが単純になった data[j] = data[j – 1]; } else { for ( ; value < data[j - 1]; --j) // ループが単純になった data[j] = data[j – 1]; } data[j] = value; } } 2014年1月18日 挿入ソート 6
  7. 7. 挿入ソートの特徴 • 時間計算量 – 要素数を N として O(N2) • N が大きいときは危険 – 入力データ列が整列済みであれば O(N) • これを期待して使うのは危険 • 使いどころ – N が小さければ高速 • クイックソートの仕上げに使うことが多い 2014年1月18日 挿入ソート 7
  8. 8. クイックソートとの連携 • クイックソートで分割する – 十分に小さくなれば挿入ソートで整列する クイックソート クイックソート 挿入ソート 2014年1月18日 挿入ソート クイックソート 挿入ソート 挿入ソート 挿入ソート 8
  9. 9. 部分ソートとは データ列の先頭 M 個の要素が 上位 M 個の要素を 整列した結果となるように並べ替える それ以外の要素の順序は問わない 2014年1月18日 挿入ソート 9
  10. 10. 挿入ソートによる部分ソート • 手順 – 先頭 M 個の要素を整列する – M + 1 個目から N 個目は以下のように操作する • M 個目の要素以上なら何もしない • そうでなければ整列状態が維持されるように挿入する • 時間計算量 – O(M・N) • M が小さければ高速 2014年1月18日 挿入ソート 10
  11. 11. 部分ソートの実行例 • 入力データ列(N = 7) – 初期状態 79 13 53 37 97 29 5 13 53 79 37 97 29 5 13 37 53 79 97 29 5 13 37 53 79 97 29 5 13 29 37 79 97 53 5 5 13 29 79 97 53 37 • 整列手順(M = 3) – 初期整列 – 37 を挿入 – 79 を挿入 – 29 を挿入 – 5 を挿入 – 完了 2014年1月18日 挿入ソート 11
  12. 12. 部分ソートの実装例 void partial_sort(int *data, size_t N, size_t M) { insertion_sort(data, M); for (size_t i = M; i < N; ++i) { int value = data[i]; if (value >= data[M – 1]) continue; data[i] = data[M – 1]; size_t j = M - 1; for ( ; (j > 0) && (value < data[j - 1]); --j) data[j] = data[j – 1]; data[j] = value; } } 2014年1月18日 挿入ソート 12
  13. 13. 番兵による効率化(再掲) • if (value < data[0]) – すべての要素を後ろにずらす – ループ条件から “value < data[j – 1]” がなくなる • else – data[0] が番兵に挿入位置を探す – ループ条件から “j > 0” がなくなる • 参考資料 – STL の実装(/usr/include/c++/bits/stl_algo.h) 2014年1月18日 挿入ソート 13
  14. 14. 順位指定による部分ソート • 順位指定とは – 上位 M 個の代わりに上位 M 位までを整列する • 実装方法 – 上位 M 位に含まれる要素の数を維持する – 面倒なので詳細は省略 • 時間計算量 – O(M・N) 2014年1月18日 挿入ソート 14
  15. 15. おわりに • 使いどころについて – 小規模なデータ列に強い • 連携について – マージソートの初期段階にも使える • 部分ソートについて – アイデアはほかの整列アルゴリズムでも使える – ヒープソートの方が大きな M に対応できる 2014年1月18日 挿入ソート 15

×