int find(int n,int a[],int l)
{
int low=0;
int high=l-1;
int middle=0;
while(low<high)
{
middle=(low+high)>>1;
if(n==a[middle])
{
printf("%d,%d",n,middle);
return 1;
}
else if(n>a[middle])
low=middle+1;
else
high=middle-1;
}
return 0;
}
int main()
{
int a[]={2,3,5,6,7,8,9,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60};
int l=sizeof(a)/sizeof(a[0]);
int i=0,n;
printf("arry content");
for(i=0;i<l;i++)
{
if(i%8==0)
printf("\n");
printf("%4d",a[i]);
}
printf("\nseach n is ");
scanf("%d",&n);
if(!find(n,a,l))
printf("not fond");
return 0;
}
二分查找的基本思想是:(設R[low..high]是當前的查找區間)
(1)首先確定該區間的中點位置:
(2)然后將待查的K值與R[mid].key比較:若相等,則查找成功並返回此位置,否則須確定新的查找區間,繼續二分查找,具體方法如下:
①若R[mid].key>K,則由表的有序性可知R[mid..n].keys均大於K,因此若表中存在關鍵字等於K的結點,則該結點必定是在位置mid左邊的子表R[1..mid-1]中,故新的查找區間是左子表R[1..mid-1]。
②類似地,若R[mid].key<K,則要查找的K必在mid的右子表R[mid+1..n]中,即新的查找區間是右子表R[mid+1..n]。下一次查找是針對新的查找區間進行的。
因此,從初始的查找區間R[1..n]開始,每經過一次與當前查找區間的中點位置上的結點關鍵字的比較,就可確定查找是否成功,不成功則當前的查找區間就縮小一半。這一過程重復直至找到關鍵字為K的結點,或者直至當前的查找區間為空(即查找失敗)時為止。
二分查找算法
int BinSearch(SeqList R,KeyType K)
{ //在有序表R[1..n]中進行二分查找,成功時返回結點的位置,失敗時返回零
int low=1,high=n,mid; //置當前查找區間上、下界的初值
while(low<=high){ //當前查找區間R[low..high]非空
mid=(low+high)/2;
if(R[mid].key==K) return mid; //查找成功返回
if(R[mid].kdy>K)
high=mid-1; //繼續在R[low..mid-1]中查找
else
low=mid+1; //繼續在R[mid+1..high]中查找
}
return 0; //當low>high時表示查找區間為空,查找失敗
} //BinSeareh
二分查找的優點和缺點
雖然二分查找的效率高,但是要將表按關鍵字排序。而排序本身是一種很費時的運算。既使采用高效率的排序方法也要花費O(nlgn)的時間。
二分查找只適用順序存儲結構。為保持表的有序性,在順序結構里插入和刪除都必須移動大量的結點。因此,二分查找特別適用於那種一經建立就很少改動、而又經常需要查找的線性表。
對那些查找少而又經常需要改動的線性表,可采用鏈表作存儲結構,進行順序查找。鏈表上無法實現二分查找。
二分法排序
#include <stdlib.h>
#include <stdio.h>
void TwoInsertSort(int array[],int n)
{
int left,right,num;
int middle,j,i;
for(i = 1;i < n;i++)
{
left = 0;// 准備
right = i-1;
num = array[i];
while( right >= left)// 二分法查找插入位置
{
middle = ( left + right ) / 2; // 指向已排序好的中間位置
if( num < array[middle] )// 即將插入的元素應當在在左區間
right = middle-1;
else // 即將插入的元素應當在右區間
left = middle+1;
}
for( j = i-1;j >= left;j-- )// 后移排序碼大於R[i]的記錄
array[j+1] = array[j];
array[left] = num;// 插入
}
}
int rcmp( const int *a, const int *b)
{
return (*a-*b);
}
void main()
{
int array[50];
int i;
printf("The original array is :\n");
for( i=0; i<50; i++ )//數組初始化並顯示
{
array[i] = 50-i;
printf("array[%d]:%d\n", i, array[i]);
}
TwoInsertSort(array,sizeof(array)/sizeof(int));//二分法排序
printf("\nAfter sorted :\n");
for( i=0; i<50; i++ )
printf("array[%d]:%d\n", i, array[i]);
//庫函數bsearch用二分法查找一個有序數組中的一個特定數,並返回該數的地址
a = (int *)bsearch(&b, numarray, sizeof(numarray)/sizeof(numarray[0]), sizeof(int),rcmp);
}