zoukankan      html  css  js  c++  java
  • 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(" ");
    printf("%4d",a[i]);



    }
    printf(" seach 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 : ");
     for( i=0; i<50; i++ )//数组初始化并显示
     {
      array[i] = 50-i;
      printf("array[%d]:%d ", i, array[i]);
     }
     TwoInsertSort(array,sizeof(array)/sizeof(int));//二分法排序
     printf(" After sorted : ");
     for( i=0; i<50; i++ )
      printf("array[%d]:%d ", i, array[i]);

    //库函数bsearch用二分法查找一个有序数组中的一个特定数,并返回该数的地址

     a = (int *)bsearch(&b, numarray, sizeof(numarray)/sizeof(numarray[0]), sizeof(int),rcmp);

    }

  • 相关阅读:
    阿里云应用开发
    [New Portal]Windows Azure Virtual Machine (7) 删除Virtual Machine
    Windows Azure Affinity Groups (2) 创建Windows Azure Affinity Groups 地缘组
    [New Portal]Windows Azure Virtual Machine (8) Virtual Machine高可用(上)
    [New Portal]Windows Azure Virtual Machine (6) 指定Virtual Machine存储账户
    [New Portal]Windows Azure Storage (13) 本地冗余存储 vs 地理冗余存储 (下)
    [New Portal]Windows Azure Virtual Machine (9) Virtual Machine高可用与自动负载均衡(下)
    树控件的整理
    很好用的数据恢复软件
    JS日历控件
  • 原文地址:https://www.cnblogs.com/locean/p/5579593.html
Copyright © 2011-2022 走看看