《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
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值