文字どおりたくさんのデータの中から目的のデータ(キー)がどこにあるか(もしくは,あるかな いか)を調べる作業である.整数のデータが配列に格納されている場合について,目的のデータを探す方法を 学習した.
このアルゴリズムの計算のオーダーは, である.なぜならば,端から探索していく ため,データが一致するためには平均 回の比較が必要であるからである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 |
著作者 | 紀平拓男・春日伸弥 |
出版社 | ソフトバンク パブリッシング株式会社 |