001 /*
002 * LAPIS lightweight structured text processing system
003 *
004 * Copyright (C) 1998-2002 Carnegie Mellon University,
005 * Copyright (C) 2003 Massachusetts Institute of Technology.
006 * All rights reserved.
007 *
008 * This library is free software; you can redistribute it
009 * and/or modify it under the terms of the GNU General
010 * Public License as published by the Free Software
011 * Foundation, version 2.
012 *
013 * LAPIS homepage: http://graphics.lcs.mit.edu/lapis/
014 */
015
016
017 package lapisx.util;
018
019 /**
020 * Binary search routines.
021 */
022 public abstract class BinarySearch {
023 public static Debug debug = Debug.QUIET;
024
025 /**
026 * Search a sorted array of integers.
027 * @param array Array of integers
028 * @param offset Starting offset of subarray to search
029 * @param length Length of subarray to search
030 * @param x Value to search for
031 * @return largest index i in subarray (offset <= i <= offset+length)
032 * such that all elements below i in the subarray are strictly less
033 * than x. If x is found in the subarray, then array[i] == x (and i is
034 * the first occurence of x in the subarray). If x is not found,
035 * then array[i] is where x should be inserted in the sort order.
036 */
037 public static int search (int[] array, int offset, int length, int x) {
038 // handle 0-length subarray case right away
039 if (length <= 0)
040 return offset;
041
042 int low = offset;
043 int high = offset+length-1;
044 // since length > 0, array[low] and array[high] are valid indices
045
046 if (x <= array[low])
047 return low;
048 if (x > array[high])
049 return high+1;
050
051 while (low+1 < high) {
052 // loop invariant: array[low] < x <= array[high],
053 // offset <= low < high < offset+length
054 int mid = (low + high)/2;
055 if (x <= array[mid])
056 high = mid;
057 else
058 low = mid;
059 }
060 // now we have array[low] < x <= array[high]
061 // && (low+1 == high || low == high)
062 // implies low+1 == high
063 debug.assertion (low+1 == high);
064 return high;
065 }
066 }