如何在递归二进制搜索中显示新中间位置

时间:2014-09-11 03:20:28

标签: java recursion binary-search

所以我的任务是实现递归二进制搜索以在整数数组中查找目标值。我把所有代码都关闭了,但是我遇到了这个部分的问题:在每次递归调用中,输出你正在检查的中间值与你的目标值。如果中间值与目标不匹配,请指明下一轮是否将检查搜索数组的上半部分或下半部分。

这是我的代码:

public class anArray {

    private long[] a; // reference to array a in anArray()
    private int nElems; // number of elements 

    public anArray(int max) // constructor
    {
        a = new long[max]; // creates new array
        nElems = 0;
    }

    public int size() // this will return the size of the array, 
    {                                  // or number of elements
        return nElems;
    }

    public int find(long search) // constructor to find search 
    {
        return recFind(search, 0, nElems - 1);
    }

    private int recFind(long search, int lowerBound, int upperBound) {
        int mid = (lowerBound + upperBound) / 2;
        if (search == a[mid]) {
            return mid;  // value found at anArray[mid]
        } else if (lowerBound > upperBound) {
            return nElems; // can't find it
        } else // divide range
        {
            if (a[mid] < search) // it's in the upper half
            {
                return recFind(search, mid + 1, upperBound);
            } else // it's in the lower half
            {
                return recFind(search, lowerBound, mid - 1);
            }
        }
    }

    public void insert(long v) // put element into array
    {
        int j;
        for (j = 0; j < nElems; j++) // find where it goes
        {
            if (a[j] > v) // linear search
            {
                break;
            }
        }

        for (int k = nElems; k > j; k--) // move bigger ones up
        {
            a[k] = a[k - 1];
        }
        a[j] = v;      // insert it
        nElems++;     // increment size
    }

    public void display() // displays array elements
    {
        for (int j = 0; j < nElems; j++) // for each element,
        {
            System.out.println(a[j] + " ");     // display it.
        }
        System.out.println(" ");
    }
}

我的演示:

public class BinarySearchDemo {

    public static void main(String[] args) {
        int maxSize = 21;   // array size
        anArray arr;        // reference to array
        arr = new anArray(maxSize);  // create the array

        arr.insert(45);   // insert elements
        arr.insert(78);
        arr.insert(98);
        arr.insert(12);
        arr.insert(56);
        arr.insert(45);
        arr.insert(12);
        arr.insert(78);
        arr.insert(63);
        arr.insert(45);
        arr.insert(78);
        arr.insert(45);
        arr.insert(77);
        arr.insert(12);
        arr.insert(80);
        arr.insert(82);
        arr.insert(78);
        arr.insert(54);
        arr.insert(65);
        arr.insert(80);
        arr.insert(50);

        arr.display();  // displays array 

        int search = 82;  // search for item
        if (arr.find(search) != arr.size()) {
            System.out.println("Found " + search);
        } else {
            System.out.println("Can't find " + search);
        }
    }
}

感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

如果我了解你,那么你需要改变这个

private int recFind(long search, int lowerBound, int upperBound) {
  int mid = (lowerBound + upperBound) / 2;
  if (search == a[mid])
    return mid;  // value found at anArray[mid]
  else if (lowerBound > upperBound)
    return nElems; // can't find it
  else  {
    if (a[mid] < search) // it's in the upper half
      return recFind(search, mid+1, upperBound);
    else      // it's in the lower half
      return recFind(search, lowerBound, mid-1); 
  }
}

添加大括号,打印您的评论所说的内容。这就像

private int recFind(long search, int lowerBound, int upperBound) {
  int mid = (lowerBound + upperBound) / 2;
  if (search == a[mid]) {
    System.out.printf("%d found at pos = %d%n", search, mid);
    return mid;  // value found at anArray[mid]
  } else if (lowerBound > upperBound) {
    System.out.printf("%d NOT found return = %d%n", search, nElems);
    return nElems; // can't find it
  } else {
    if (a[mid] < search) { // it's in the upper half
      System.out.printf("%d search, recurse upper half from position%d%n", 
          search, mid);
      return recFind(search, mid+1, upperBound);
    } else {               // it's in the lower half
      System.out.printf("%d search, recurse lower half from position%d%n", 
          search, mid);
      return recFind(search, lowerBound, mid-1);
    } 
  }
}

答案 1 :(得分:2)

您应该检查if (lowerBound > upperBound)作为函数中的第一个检查,否则您可能会陷入无限循环。

这部分:

  

输出您正在检查的中间值与目标值

计算mid后,可以像下面的print语句一样简单:

System.out.println("Checking mid=" + a[mid] + " against target=" + search);

现在这部分:

  

如果中间值与目标不匹配,请指明下一轮是否会检查搜索数组的上半部分或下半部分。

同样,只要您确定a[mid]是小于还是大于search,就会打印出来。

if (a[mid] < search) {
    System.out.println("examining upper half");
}

类似地:

if (a[mid] > search) {
    System.out.println("examining bottom half");
}

另外,对{}语句使用if/else以确保所有内容都在正确的范围内。

将这些更改应用于您的代码:

private int recFind(long search, int lowerBound, int upperBound) {
    if (lowerBound > upperBound) {
        return nElems; // can't find it
    }

    int mid = (lowerBound + upperBound) / 2;

    // print mid and target
    System.out.println("Checking mid= " + a[mid] + " against target=" + search");

    if (search == a[mid]) {
        return mid;  // value found at anArray[mid]
    }
    else             // divide range
    {
        if (a[mid] < search) { // it's in the upper half
            System.out.println("examining upper half");
            return recFind(search, mid+1, upperBound);
        }

        else  {               // it's in the lower half
            System.out.println("examining bottom half");
            return recFind(search, lowerBound, mid-1); 
        }
    }
}