C語言的算法--------二分法查找



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);

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM