来自维基百科:
“在计算机科学中,二分搜索是一种算法,用于通过检查中间位置来定位排序列表中元素的位置,从考虑中排除一半列表,然后对剩余的一半执行搜索。[1 ][2]如果中间元素等于查找的值,则说明位置已经找到;否则,根据该元素大于还是小于中间元素,选择上半部分或下半部分进行搜索。"
所以二分查找的前提是数据是有序的。它必须进行排序,因为它将数组切成两半并查看中间元素。如果中间元素是它正在寻找的东西,它就完成了。如果中间元素较大,则它占用数组的下半部分。如果中间元素较小,则为数组的上半部分。然后重复该过程(查看中间等...),直到找到(或未找到)元素。
如果数据未排序,算法将无法工作。
所以你会做这样的事情:
final String[] data;
final int index;
data = new String[] { /* init the elements here or however you want to do it */ };
Collections.sort(data);
index = Arrays.binarySearch(data, value);
或者,如果您不想对其进行排序,请进行线性搜索:
int index = -1; // not found
for(int i = 0; i < data.length; i++)
{
if(data[i].equals(value))
{
index = i;
break; // stop looking
}
}
为了完整起见,这里有一些完整方法的变体:
// strict one - disallow nulls for everything
public <T> static int linearSearch(final T[] data, final T value)
{
int index;
if(data == null)
{
throw new IllegalArgumentException("data cannot be null");
}
if(value == null)
{
throw new IllegalArgumentException("value cannot be null");
}
index = -1;
for(int i = 0; i < data.length; i++)
{
if(data[i] == null)
{
throw new IllegalArgumentException("data[" + i + "] cannot be null");
}
if(data[i].equals(value))
{
index = i;
break; // stop looking
}
}
return (index);
}
// 允许所有内容为空
public static <T> int linearSearch(final T[] data, final T value)
{
int index;
index = -1;
if(data != null)
{
for(int i = 0; i < data.length; i++)
{
if(value == null)
{
if(data[i] == null)
{
index = i;
break;
}
}
else
{
if(value.equals(data[i]))
{
index = i;
break; // stop looking
}
}
}
}
return (index);
}
您可以填写其他变体,例如不允许空数据数组,或不允许在值中出现空值,或不允许在数组中出现空值。 :-)
基于 cmets,这也与 permissive 相同,并且由于您没有编写大部分代码,因此它会比上面的版本更好。如果您希望它是偏执的,并且不允许任何内容为 null,那么您会被上面的偏执版本卡住(并且此版本基本上与其他版本一样快,因为方法调用 (asList) 的开销可能会在运行时消失)。
public static <T> int linearSearch(final T[] data, final T value)
{
final int index;
if(data == null)
{
index = -1;
}
else
{
final List<T> list;
list = Arrays.asList(data);
index = list.indexOf(value);
}
return (index);
}