文字どおりたくさんのデータの中から目的のデータ(キー)がどこにあるか(もしくは,あるかな いか)を調べる作業である.整数のデータが配列に格納されている場合について,目的のデータを探す方法を 学習した.
このアルゴリズムの計算のオーダーは,
である.なぜならば,端から探索していく
ため,データが一致するためには平均
回の比較が必要であるからである4.
1 int linear_search(int x,int *a,int num)
2 {
3 int n=0;
4
5 /* 配列の範囲内で目的の値を探す */
6 while(n<num&&a[n]!=x)
7 n++;
8
9 if(n<num)
10 return n;
11
12 return NOT_FOUND;
13 }
n<num&&a[n]!=x
このようにすると,比較の数が半分になる.しかし,計算量のオーダーは
と変わら
ないことに注意しよう.
1 int search(int x,int *a,int num)
2 {
3 int n=0,t;
4
5 /* 最後の値をxに入れ替える(番兵) */
6 t=a[num-1];
7 a[num-1]=x;
8
9 /*目的の値を探す*/
10 while(a[n]!=x)
11 n++;
12
13 a[num-1]=t; /* 配列最後の値を元に戻す */
14 if(n<num-1)
15 return n; /* いちばん最後以外で一致 */
16 if(x==t)
17 return n; /* いちばん最後が一致 */
18
19 return NOT_FOUND;
20 }
たとえば,データが昇順に並んでいた場合,端から比較するのではなく,最初に真ん中に位置す
るデータと比較する.すると,サーチすべきデータの個数が1回の比較でに半分になる.同じこ
とを繰り返すと,比較すべき対象が
ずつ減少する.データの個数が多い場合,この
方法は劇的にサーチが早くなる.この方法をバイナリーサーチと言う.
リニアサーチだと,1回の比較で1個しかデータの候補が減らないのに,バイナリーサーチ だと半分に減少させることができるのである.ただし,バイナリーサーチを使うために は,データを予めソートしておく必要がある.サーチの回数が1回であれば,ソートの手 間を考えるとリニアサーチの方が良い.サーチの回数が増加すると,バイナリーサーチの 方が有利になる.
1回の計算,リスト9の5〜15行のループで,検索する範囲は
にな
る.したがって,
回のループでその範囲が1になれば計算が終了する.データの
個数を
として,式で表すと,
![]() |
(2) |
| (3) |
1 int binary_search(int x,int *a,int left,int right)
2 {
3 int mid;
4
5 while(left<=right)
6 {
7 mid=(left+right)/2;
8 if(a[mid]==x)
9 return mid;
10
11 if(a[mid]<x)
12 left=mid+1; /* midより左側にxは存在しない */
13 else
14 right=mid-1; /* midより右側にxは存在しない */
15 }
16
17 /* サーチ範囲がなくなっても一致するものはなかった */
18 return NOT_FOUND;
19 }
[転載について]
このペー
ジ中のリスト7とリスト8,リスト9のプロ
グラムは,教科書として使用している以下の書籍
| 書名 | プログラミングの宝箱 アルゴリズムとデータ構造 ISBN4-7973-2419-8 |
| 著作者 | 紀平拓男・春日伸弥 |
| 出版社 | ソフトバンク パブリッシング株式会社 |