查找算法是计算机科学中最基本的算法之一,其用途在查找给定序列中的特定值。
最差 | O(logn)O(logn) |
---|
最好 | O(1)O(1) |
平均 | O(logn)O(logn) |
最坏空间 | O(1) |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| def binary_search(self, A, target):
'''
二分查找法
'''
# 检查输入
if len(A) < 1 or target < A[0] or target > A[-1]:
return -1
l, r = 0, len(A)-1
while l < r: #退出条件,注意不要用l == r判断
m = (l + ( r - l )) >> 1 #计算二分点, 要防止溢出
if A[m] == target: #find
return m
elif target < A[m]: # l....target....m............r
r = m # 右边界直接移动
else:
l = m + 1 # 左边界移动时要+1
return -1
|
项目 | 复杂度 |
---|
Worst | $O(n)$ |
Best | O(1) |
Average | O(n) |
Average | O(loglogn) on uniform distributed data |
Worst space | O(1) |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
| pub fn interpolation_search(
arr: &[i32],
target: &i32,
) -> Result<usize, usize> {
// 1. Handle empty sequence.
if arr.is_empty() {
return Err(0)
}
// 2. Setup variable storing iteration informaion.
let mut hi = arr.len() - 1;
let mut lo = 0_usize;
let mut interpolant = 0_usize;
// 3. Main loop to calculate the interpolant.
loop {
let lo_val = arr[lo];
let hi_val = arr[hi];
// 3.1. Three condition to exit the loop
if hi <= lo || *target < lo_val || *target > hi_val {
break
}
// 3.2. The linear interpolation part
let offset = (*target - lo_val) * (hi - lo) as i32 / (hi_val - lo_val);
interpolant = lo + offset as usize;
let mid_val = arr[interpolant];
// 3.3. Comparison between the interpolant and targert value.
if mid_val > *target {
hi = interpolant - 1;
} else if mid_val < *target {
lo = interpolant + 1;
} else {
break
}
}
// 4. Determine whether the returning interpolant are equal to target value.
if *target > arr[hi] {
Err(hi + 1)
} else if *target < arr[lo] {
Err(lo)
} else {
Ok(interpolant)
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| use crate::searching::binary_search;
pub fn exponential_search<T>(arr: &[T], target: &T) -> Result<usize, usize>
where T: PartialOrd
{
// 1. Handle empty scenario.
let size = arr.len();
if size == 0 {
return Err(0);
}
// 2. Determine searching boundaries.
let mut hi = 1_usize; // Upper bound.
while hi < size && arr[hi] < *target {
hi <<= 1;
}
let lo = hi >> 1; // Lower bound.
// 3. Do binary search.
binary_search(&arr[lo..size.min(hi + 1)], target)
.map(|index| lo + index)
.map_err(|index| lo + index)
}
|
- 線性搜尋 Linear search - Rust Algorithm Club