在cs50 pset3二进制搜索中陷入while循环

在cs50 pset3二进制搜索中陷入while循环,c,cs50,C,Cs50,我正在尝试使用while循环实现二进制搜索。当我要查找的int在数组中时,它似乎起作用;但是,当我正在搜索的int不存在时,程序似乎陷入了循环中,而没有返回false。我一直在使用gdb,但我似乎仍然无法找出错误。正如你所看到的,我可能已经添加了一些额外的if语句等,试图弄明白这一点 bool search(int value, int values[], int n) { sort(values, n); int begin = 0; int end = (n - 1

我正在尝试使用
while
循环实现二进制搜索。当我要查找的
int
在数组中时,它似乎起作用;但是,当我正在搜索的
int
不存在时,程序似乎陷入了循环中,而没有返回false。我一直在使用gdb,但我似乎仍然无法找出错误。正如你所看到的,我可能已经添加了一些额外的if语句等,试图弄明白这一点

bool search(int value, int values[], int n) {
    sort(values, n);

    int begin = 0;
    int end = (n - 1);

    if (n < 1) {
        return false;
    }
    while (end > begin + 1) {
        int center = ((begin + end) / 2);
        if (values[0] == value) {
            return true;
        }
        if (begin == value) {
            return true;
        }
        if (end == value) {
            return true;
        }
        if (end == (begin + 1) || end == begin) {
            if (end == value || begin == value) {
                return true;
            } else {
                return false;
            }
        }
        if ((values[center]) == value) {
            return true;
        } else
        if ((values[center]) > value) {
            end = center;
        } else
        if ((values[center]) < value) {
            begin = center;
        } else {
            return false;
        }
    }
    // TODO: implement a searching algorithm
    return false;
}
bool搜索(int值,int值[],int n){
排序(值,n);
int begin=0;
int end=(n-1);
if(n<1){
返回false;
}
while(结束>开始+1){
int中心=((开始+结束)/2);
如果(值[0]==值){
返回true;
}
如果(开始==值){
返回true;
}
if(end==值){
返回true;
}
如果(结束==(开始+1)|结束==开始){
如果(结束==值| |开始==值){
返回true;
}否则{
返回false;
}
}
如果((值[中心]==值){
返回true;
}否则
如果((值[中心])>值){
端=中心;
}否则
如果((值[中心]<值){
开始=中心;
}否则{
返回false;
}
}
//TODO:实现一个搜索算法
返回false;
}

为什么要这样做

if (values[0]==value)
    {
        return true;
    }
    if (begin == value)
    {
        return true;
    }
    if (end == value)
    {
        return true;
    }
    if (end == (begin+1) || end == begin)
    {
        if (end == value || begin == value)
        {
        return true;
        } 
        else
        {
        return false;
        }
    }
它们不是必需的。你可以像下面这样做

while(end>beg+1 && values[center]!=value)
     {
     if ((values[center])>value)
        end = center-1;
    else if (values[center]<value)
        begin = center+1;
    center=(end+begin)/2;
     }
     if(values[center]==value)
           return true;
     else return false;
    }
while(end>beg+1&&values[center]!=value)
{
如果((值[中心])>值)
结束=中心-1;

否则,如果(values[center]您不必要地过度复杂化了这件简单的事情。 您可以删除代码中的所有额外内容并使用

   `if ((values[center])==value)
    {
        return true;
    }
    else if ((values[center])>value)
    {
        end = center-1;
    }
    else if ((values[center])<value)
    {
        begin = center+1;
    }
`if((值[中心]==值)
{
返回true;
}
else if((值[中心]>值)
{
结束=中心-1;
}

否则如果((values[center])您的代码太复杂。以下是一些提示:

  • 您应该使用包含左索引而排除右索引的范围,这在C中是惯用的,并且会导致更简单的算法

  • 您应该计算
    center=start+(end-start)/2;
    而不是
    center=(start+end)/2;
    ,以避免
    start
    end
    非常大时可能出现的整数溢出

  • 数组大小的类型应为
    size\u t
    ,可能大于
    int

  • 将该值与范围中间的元素值进行比较:

    • 如果相等,则找到该值,返回true
    • 如果较小,则将范围缩小到左侧,中心除外
    • 否则,将范围缩小到右侧,中心除外
  • 如果范围为空,则未找到该值,返回false

以下是一个更简单的版本:

bool search(int value, int values[], size_t n) {
    // Assuming values is sorted before calling this function
    //sort(values, n);

    size_t begin = 0;
    size_t end = n;

    while (begin < end) {
        size_t center = begin + (end - begin) / 2;
        if (value == values[center]) {
            return true;
        }
        if (value < values[center]) {
            end = center;
        } else {
            begin = center + 1;
        }
    }
    return false;
}
bool搜索(int值,int值[],大小){
//假设在调用此函数之前对值进行了排序
//排序(值,n);
大小\u t begin=0;
尺寸=n;
while(开始<结束){
尺寸\u t中心=开始+(结束-开始)/2;
如果(值==值[中心]){
返回true;
}
如果(值<值[中心]){
端=中心;
}否则{
开始=中心+1;
}
}
返回false;
}

开始
结束
都是索引,为什么要将它们与
进行比较?这里有很多二进制搜索算法可用(肯定会有,而且相当多的算法也会与CS50相关)。您应该查看其中的一些代码,看看您的代码是否过于复杂和不正确。例如,中有一个有用的代码,它处理一些比您需要的更复杂的情况,但也包含您需要的代码。您也可以查看。@aknys:您可以通过单击其s下方的灰色复选标记来接受其中一个答案。@aknys:核心。