如何递归地使用指数,二进制或插值搜索找到索引?

时间:2013-10-02 18:16:47

标签: java algorithm sorting pseudocode

  

给定n个整数A [0 ... n-1]的数组,使得∀i,0≤i≤n,我们得到| A [i] -A [i + 1] |≤1,如果A [0] = x,A [n-1] = y,我们得到x

我不明白这个问题。我被困4天了。知道怎么用递归方式进行二分搜索,指数搜索或插值搜索?我们给出一个元素z找到索引j使得a [j] = z(a j)我是对的吗?

static int binarySearch(int[] searchArray, int x) {
                    int start, end, midPt;
                    start = 0;
                    end = searchArray.length - 1;
                    while (start <= end) {
                            midPt = (start + end) / 2;
                            if (searchArray[midPt] == x) {
                                    return midPt;
                            } else if (searchArray[midPt] < x) {
                                    start = midPt + 1;
                            } else {
                                    end = midPt - 1;
                            }
                    }
                    return -1;
            }

2 个答案:

答案 0 :(得分:1)

您可以使用基本的二进制搜索算法。 A[i]A[i+1]最多相差1的事实可以保证您找到匹配项。

伪代码:

search(A, z):
  start := 0
  end := A.length - 1
  while start < end:
    x = A[start]
    y = A[end]
    mid := (start+end)/2
    if x <= z <= A[mid]:
      end := mid
    else if A[mid] < z <= y
      start := mid + 1
  return start

请注意,这并不一定会返回第一场比赛,但这并不是必需的。

答案 1 :(得分:0)

要应用您的算法,您需要一个排序数组。 问题的条件是你有一个数组,其元素与max 1不同,不一定排序!!!

所以,这是编写代码的步骤:

  1. 检查问题数据是否符合给定的条件
  2. 排序输入数组+保存旧索引值,以便以后可以初始化元素位置
  3. 以递归方式实现搜索方法
  4. Binary search source
  5. Interpolation search source
  6. 以下是完整的示例来源:

    public class Test {
    
    // given start ======================================================
    public int[] A = new int[] { 1, 1, 2, 3, 4, 4, 3, 2, 1, 1, 2, 3, 4, 5, 6,
            7, 8 };
    public int z = 4;
    // given end =======================================================
    
    public int[] indexes = new int[A.length];
    
    public static void main(String[] args) throws Exception {
        Test test = new Test();
        if (test.z < test.A[0] || test.z > test.A[test.A.length - 1]){
            System.out.println("Value z="+test.z+" can't be within given array");
            return;
        }
        sort(test.A, test.indexes);
        int index = binSearch(test.A, 0, test.A.length, test.z);
        if (index > -1) {
            System.out.println("Binary search result index =\t"
                    + test.indexes[index]);
        }
        index = interpolationSearch(test.A, test.z, 0, test.A.length-1);
        if (index > -1) {
            System.out.println("Binary search result index =\t"
                    + test.indexes[index]);
        }
    }
    
    public static void sort(int[] a, int[] b) {
        for (int i = 0; i < a.length; i++)
            b[i] = i;
        boolean notSorted = true;
        while (notSorted) {
            notSorted = false;
            for (int i = 0; i < a.length - 1; i++) {
                if (a[i] > a[i + 1]) {
                    int aux = a[i];
                    a[i] = a[i + 1];
                    a[i + 1] = aux;
                    aux = b[i];
                    b[i] = b[i + 1];
                    b[i + 1] = aux;
                    notSorted = true;
                }
            }
        }
    }
    
    public static int binSearch(int[] a, int imin, int imax, int key) {
        // test if array is empty
        if (imax < imin)
            // set is empty, so return value showing not found
            return -1;
        else {
            // calculate midpoint to cut set in half
            int imid = (imin + imax) / 2;
    
            // three-way comparison
            if (a[imid] > key)
                // key is in lower subset
                return binSearch(a, imin, imid - 1, key);
            else if (a[imid] < key)
                // key is in upper subset
                return binSearch(a, imid + 1, imax, key);
            else
                // key has been found
                return imid;
        }
    }
    
    public static int interpolationSearch(int[] sortedArray, int toFind, int low,
            int high) {
    
        if (sortedArray[low] == toFind)
            return low;
    
        // Returns index of toFind in sortedArray, or -1 if not found
        int mid;
    
        if (sortedArray[low] <= toFind && sortedArray[high] >= toFind) {
            mid = low + ((toFind - sortedArray[low]) * (high - low))
                    / (sortedArray[high] - sortedArray[low]); // out of range is
                                                                // possible here
            if (sortedArray[mid] < toFind)
                low = mid + 1;
            else if (sortedArray[mid] > toFind)
                // Repetition of the comparison code is forced by syntax
                // limitations.
                high = mid - 1;
            else
                return mid;
            return interpolationSearch(sortedArray, toFind, low, high);
    
        } else {
            return -1;
        }
    
    }
    
    }