たとえば,データが昇順に並んでいた場合,端から比較するのではなく,最初に真ん中に位置す るデータと比較する.すると,サーチするデータの個数がいっぺんに半分になる.同じこ とを繰り返すと,比較すべき対象が ずつ減少する.データの個数が多い場合,この 方法は劇的にサーチが早くなる.この方法をバイナリーサーチと言う.
リニアサーチだと,1回の比較で1個しかデータの候補が減らないのに,バイナリーサーチ だと 個減少させることができるのである.ただし,バイナリーサーチを使うために は,データを予めソートしておく必要がある.サーチの回数が1回であれば,ソートの手 間を考えるとリニアサーチの方が良い.サーチの回数が増加すると,バイナリーサーチの 方が有利になる.
つぎに, とキーxを比較する.この比較の結果,
1回の計算,リスト3の12〜22行のループで,検索する範囲は にな る.したがって, 回のループでその範囲が1になれば計算が終了する.データの 個数を として,式で表すと,
(1) |
(2) |
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <time.h> 4 5 #define NOT_FOUND (-1) 6 #define N (10) 7 8 int binary_search(int x,int *a,int left,int right) 9 { 10 int mid; 11 12 while(left<=right) 13 { 14 mid=(left+right)/2; 15 if(a[mid]==x) 16 return mid; 17 18 if(a[mid]<x) 19 left=mid+1; /* midより左側にxは存在しない */ 20 else 21 right=mid-1; /* midより右側にxは存在しない */ 22 } 23 24 /* サーチ範囲がなくなっても一致するものはなかった */ 25 return NOT_FOUND; 26 } 27 28 int main(void) 29 { 30 int i,r,array[N]; 31 32 srand((unsigned int)time(NULL)); 33 34 /* 適当なソートされた配列を作る */ 35 printf("array "); 36 printf("[0]:%d ",array[0]=rand()%3); 37 for(i=1;i<N;i++) 38 printf("[%d]:%d ",i,array[i]=array[i-1]+rand()%3); 39 40 printf("\n何を探しますか:"); 41 scanf("%d",&i); 42 43 r=binary_search(i,array,0,N-1); 44 45 if(r==NOT_FOUND) 46 printf("%dは見つかりません\n",i); 47 else 48 printf("%dは%d番目です\n",i,r); 49 50 return EXIT_SUCCESS; 51 }
このように,先頭を知りたい場合は必ずとなり通しと比較するようにすればよい.そのよ うにするためには,3を改良して,4のようにすれば良 い.
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <time.h> 4 5 #define NOT_FOUND (-1) 6 #define N (10) 7 8 int binary_search(int x,int *a,int left,int right) 9 { 10 int mid; 11 12 while(left<right) 13 { 14 mid=(left+right)/2; 15 if(a[mid]<x) 16 left=mid+1; 17 else 18 right=mid; 19 } 20 if(a[left]==x) 21 return left; 22 23 /* サーチ範囲がなくなっても一致するものはなかった */ 24 return NOT_FOUND; 25 } 26 27 int main(void) 28 { 29 int i,r,array[N]; 30 31 srand((unsigned int)time(NULL)); 32 33 /* 適当なソートされた配列を作る */ 34 printf("array "); 35 printf("[0]:%d ",array[0]=rand()%3); 36 for(i=1;i<N;i++) 37 printf("[%d]:%d ",i,array[i]=array[i-1]+rand()%3); 38 39 printf("\n何を探しますか:"); 40 scanf("%d",&i); 41 42 r=binary_search(i,array,0,N-1); 43 44 if(r==NOT_FOUND) 45 printf("%dは見つかりません\n",i); 46 else 47 printf("%dは%d番目です\n",i,r); 48 49 return EXIT_SUCCESS; 50 }
[転載について]
このページ中のリスト3とリスト4のプロ
グラムは,教科書として使用している以下の書籍
書名 | プログラミングの宝箱 アルゴリズムとデータ構造 ISBN4-7973-2419-8 |
著作者 | 紀平拓男・春日伸弥 |
出版社 | ソフトバンク パブリッシング株式会社 |