- 顺序查找
- 逐个比较查询,如果找到返回数据或者索引,如果到最后没有找到,返回null
- 可以在顺序表中也可以在链表中
- 时间复杂度为o(n)
public static int search(int[] arr, int value) {
for (int i = 0; i < arr.length; i++) {
if (arr[i] == value) {
return i;
}
}
return -1;
}
- 二分查找
- 要求:1)、顺序存储 2)、有序序列
- 时间复杂度:o(logn)
- 先将要查找的值与顺序表中最中间的值进行比较,如果大于中间的值就在右半部分中进行相同方式的查找,否则就在左半部分中查找,如此反复进行。
- 非递归实现:
/**
* 非递归实现二分查找
*
* @param arr
* @param value
* @return
*/
public static int binarySearch(int[] arr, int value) {
int low = 0;
int high = arr.length - 1;
while (low <= high) {
int mid = (low + high) / 2;
if (arr[mid] == value) {
return mid;
} else if (value > arr[mid]) {
low = low + 1;
} else {
high = high - 1;
}
}
return -1;
}
下面用数组arr=new int[]{0,1,2,3,4,5},value=5来测试一下上面程序
- 刚进入函数low=0;high=5;
- low<high,进入第一次循环
循环次数 | low | high | mid |
---|---|---|---|
1 | 0 | 5 | 2 |
2 | 3 | 5 | 4 |
3 | 5 | 5 | 5 |
直到low=high=6时候,arr[mid]==value返回true,找到对应索引。
这里注意:循环的执行条件为low<=high而不是low<high,根据上面的例子,如果改为low<high的话,在low=high=5的情况下就不会进入循环,最后返回-1,得到错误结果。
- 递归实现二分查找:
/**
* 使用递归实现二分查找
*
* @param arr
* @param value
* @return
*/
public static int binarySearch2(int[] arr, int value) {
int low = 0;
int high = arr.length - 1;
return binarySearch2(arr, value, low, high);
}
private static int binarySearch2(int[] arr, int value, int low, int high) {
if (low > high) {
return -1;
}
int mid = (low + high) / 2;
if (arr[mid] == value) {
return mid;
} else if (value > arr[mid]) {
return binarySearch2(arr, value, mid + 1, high);
} else {
return binarySearch2(arr, value, low, mid - 1);
}
}
原理和递归实现一样,注意递归结束条件low>high。