查找
静态查找、动态查找
静态查找
1.顺序查找
技巧:建立哨兵(每次循环少判断一次,降低时间复杂度)
2.二分查找
- 有序存放
- 连续存放
关于二分查找的关键变量left,right,mid写法:
leetcode上的二分查找模板:
//1.二分查找一个数:
/*
不用mid-1和mid+1而用mid,如果找不到会死循环
注意right和退出条件影响结果
*/
int binarySearch(int[] nums, int target) {
int left = 0;
int right = nums.length - 1; // 注意
while(left <= right) { // 注意
int mid = (right + left) / 2;
if(nums[mid] == target)
return mid;
else if (nums[mid] < target)
left = mid + 1; // 注意
else if (nums[mid] > target)
right = mid - 1; // 注意
}
return -1;
}
int binarySearch(int[] nums, int target) {
int left = 0;
int right = nums.length; // 注意
while(left < right) { // 注意
int mid = (right + left) / 2;
if(nums[mid] == target)
return mid;
else if (nums[mid] < target)
left = mid + 1;
else if (nums[mid] > target)
right = mid - 1;
}
return nums[left]==target?left:-1; // 注意
}
//2.找target出现多次时的左边界
int left_bound(int[] nums, int target) {
if (nums.length == 0) return -1;
int left = 0;
int right = nums.length; // 注意
while (left < right) { // 注意
int mid = (left + right) / 2;
if (nums[mid] == target) {
right = mid;
} else if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid; // 注意
}
}
//循环退出条件: left==right
if (left == nums.length) return -1; // target 比所有数都大
return nums[left] == target ? left : -1; // 找不到target?
}
//3.找target出现多次时的右边界
int right_bound(int[] nums, int target) {
if (nums.length == 0) return -1;
int left = 0, right = nums.length;
while (left < right) {
int mid = (left + right) / 2;
if (nums[mid] == target) {
left = mid + 1; // 注意
} else if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid;
}
}
//循环退出条件: left==right
if (left == 0) return -1; // target比所有数都小
return nums[left-1] == target ? (left-1) : -1; // 找不到target?
}
二分查找判定树
二分查找的启示
由于在数组中对要查找的元素进行有序化的组织,
使得我们的查找过程是按照固定的(事先定义的)顺序进行,
这个顺序是形成一个类似像树这样的一个结构。
反过来说,能不能不一定将数据存储在数组中,
按这样一个层次化的结构来存储数据,
是否也能达到二分查找这样的效果?
(查找树,因为链式存储插入删除方便得多,解决动态查找问题)