1. 程式人生 > >《C程式設計語言》練習 3-1

《C程式設計語言》練習 3-1

練習 3-1
在上面有關折半查詢的例子中,while 迴圈語句內共執行了兩次測試,其實
只要一次就足夠(代價是將更多的測試在迴圈外執行)。重寫該函式,使得在迴圈內部只執行
一次測試。比較兩種版本函式的執行時間。

原文程式碼有一個問題,下面是改過的原文程式碼

int binsearch(int x, int v[], int n)
{
    int low, high, mid;
    low = 0;
    high = n - 1;
    while (low <= high) {
        mid = (low + high) / 2;

        if
(x < v[mid]) high = mid - 1;//原文這裡是 mid+1,會導致一個問題: x <= v[0] 時會死迴圈 else if (x > v[mid]) low = mid + 1; else /* found match */ return mid; } return -1; /* no match */ }

自己寫的程式碼
感覺沒改什麼

int binsearch2(int x, int v[], int n)
{
    int low, high, mid;
    low = 0
; high = n - 1; while (v[mid = (low + high) / 2] != x && low != high ) //沒找到 而且 沒找完 就繼續迴圈 { if (x < v[mid]) high = mid - 1; else if (x > v[mid]) low = mid + 1; } if (v[mid] == x) return mid; //找到了,返回下標 else return
-1; //沒找到,返回-1 }

while括號內的條件看起來不太友好,也可以這樣寫

int binsearch2(int x, int v[], int n)
{
    int low, high, mid;
    low = 0;
    high = n - 1;

    //自建死迴圈
    while (1) 
    {
        mid = (low + high) / 2;

        //找到了 或者 找完了 就跳出迴圈
        if (v[mid] == x || low == high) 
            break;

        if (x < v[mid])
            high = mid - 1;
        else if (x > v[mid])
            low = mid + 1;
    }

    if (v[mid] == x) 
        return mid; //找到了,返回下標
    else
        return -1; //沒找到,返回-1
}

或者裝B一點


int binsearch2(int x, int v[], int n)
{
    int low, high, mid;
    low = 0;
    high = n - 1;

    while (v[mid = (low + high) / 2] != x && low != high  )
        (x < v[mid]) ? (high = mid - 1) : (low = mid + 1);

    if (v[mid] == x) 
        return mid;
    else
        return -1;
}

這個三目不用考慮 x == v[mid] 的情況,
因為等於的話迴圈就結束了,high和low的值是什麼都無所謂

完整程式碼 :

/*練習 3-1 在上面有關折半查詢的例子中,while 迴圈語句內共執行了兩次測試,其實
只要一次就足夠(代價是將更多的測試在迴圈外執行)。重寫該函式,使得在迴圈內部只執行
一次測試。比較兩種版本函式的執行時間。*/

#include <stdio.h>

#define MAX 10000 //陣列長度


int binsearch(int x, int v[], int n);
int binsearch2(int x, int v[], int n);
main()
{
    int v[MAX];
    int i, x, n;

    //初始化陣列
    for (i = 0; i < MAX; i++)
        v[i] = i;

    //要找的數字 
    x = 0;

    //原函式
    n = binsearch(x, v, MAX);
    printf("%d\n", n);

    //自己的函式
    n = binsearch2(x, v, MAX);
    printf("%d\n", n);
}

/* binsearch: find x in v[0] <= v[1] <= ... <= v[n-1] */
int binsearch(int x, int v[], int n)
{
    int low, high, mid;
    low = 0;
    high = n - 1;
    while (low <= high) {
        mid = (low + high) / 2;

        if (x < v[mid])
            high = mid - 1;//原文這裡是 mid+1,會導致一個問題: x <= v[0] 時會死迴圈
        else if (x > v[mid])
            low = mid + 1;
        else /* found match */
            return mid;
    }
    return -1; /* no match */
}

int binsearch2(int x, int v[], int n)
{
    int low, high, mid;
    low = 0;
    high = n - 1;

    while (v[mid = (low + high) / 2] != x && low != high  ) //沒找到 而且 沒找完 就繼續迴圈
    {
        if (x < v[mid])
            high = mid - 1;
        else if (x > v[mid])
            low = mid + 1;
    }

    if (v[mid] == x) 
        return mid; //找到了,返回下標
    else
        return -1; //沒找到,返回-1
}