C基礎算法之二分法查找


算法:當數據量很大適宜采用該方法。采用二分法查找時,數據需是排好序的。 基本思想:假設數據是按升序排序的,對於給定值x,從序列的中間位置開始比較,如果當前位置值等於x,則查找成功;若x小於當前位置值,則在數列的前半段 中查找;若x大於當前位置值則在數列的后半段中繼續查找,直到找到為止。

二分法查找在針對大量有序排列的情況下發揮出很優越的效率,這里以最具規律性的數組為例,代碼如下:

 

示例代碼:

/* binarysearch2.c --- 
 * 
 * Filename: binarysearch2.c
 * Description: 用循環方式和遞歸兩種方式 實現二分法查找過程
 * Author: magc
 * Maintainer: 
 * Created: 三  7月 25 23:26:52 2012 (+0800)
 * Version: 
 * Last-Updated: 四  7月 26 00:22:37 2012 (+0800)
 *           By: magc
 *     Update #: 74
 * URL: 
 * Keywords: 遞歸 二分法查找
 * Compatibility: 
 * 
 */

/* Commentary: 
 * 
 * 
 * 
 */

/* Change Log:
 * 添加循環方式和遞歸方式
 * 
 */

/* Code: */
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>

int binarysearch(int arr[],int len,int key);
int binarysearch2(int array[],int key,int low,int high);

    
int main(int argc, char * argv[])
{
    int array[] = {3,5,6,7,11,22,44,47 };
    int i;
    printf("請參照下列數組,輸入你要查找的目標:\n {");
    int len = sizeof(array)/sizeof(int);
    
    for (i = 0; i < len; i++) {

        printf("%d,",array[i]);
        
    }
    printf("}:\n");
    int dest;
    scanf("%d",&dest);
    int res = binarysearch(array,len,dest);
    printf("1. res = %d\n",res);

    int res2 = binarysearch2(array,dest,0,len - 1);
    printf("2. res = %d\n",res2);

    
}
/**************************************************************************
函數名稱:用循環實現二分法查找過程,
功能描述:
輸入參數:
返   回:返回目標值在數組中的下標
**************************************************************************/


int binarysearch(int arr[],int len,int key)
{

    int high,low;
    high = len - 1;//假設數組是從小到大排列的
    low = 0;
    int midle = len/2;
    
    while(high >= low)
        {
            midle = (high + low)/2;
            
           if(arr[midle] == key)
               return midle;
           if(arr[midle] > key)
               high = midle - 1;         //前提是假設數組是從小到大排序,否則不確定是該加1還是減1
           else if(arr[midle] < key )
               low = midle + 1;
        }
    return (-1);
    
}
/**************************************************************************
函數名稱:用遞歸實現二分法查找
功能描述:
輸入參數:
返   回:
**************************************************************************/
int binarysearch2(int array[],int key,int low,int high)
{

    if (low >= high)
        return (-1);

    int midle = (low + high)/2;
    if(array[midle] == key)
        return midle;
    if(midle == high || midle == low) //此時,只剩下了下標為high和low的兩個數,確定另一個數不是key后,就確定查找完畢,並且未找到目標值
        {
            if(array[high] == key)
                return high;
            else if(array[low] == key)
                return low;
            else
                return (-1);            
        }

    else if(array[midle] > key)
        return binarysearch2(array,key,low,midle);  //由於不確定排序方向,所以此處只能用midle值,而不能加1或減1
    else if(array[midle] < key)                    //當中間值小於目標值時,在high的一側繼續查找,low變到midle位置上
        return binarysearch2(array,key,midle,high);
}


/* binarysearch2.c ends here */

 

 在GCC下編譯運行結果如下:

 注:

1)在第一個方法中,

要體會到二分法查找的思路,設置high和low參數的好處是,不論數組是從大到小還是從小到大排列,此函數皆適用。

注意把握此例中high和low的變更過程,特別是邊界,當high和low相鄰時,取到的midle值總是二者之一,若繼續查找,便進入死循環狀態,此時確定沒有目標值,退出查找

3)理解遞歸的思路,凡可以遞歸的問題,一般用循環也能實現(反之不然),如binarysearch2方法。

 

在整理思路時,要准確把握變與不變因素,進而實現

 

 

 


免責聲明!

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



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