介绍
顺序查找,也叫 线性查找,将待查找的元素 key,与表中第一个元素进行比较,一个一个往后比对,如果存在 key ,则返回查找成功;否则,返回查找失败。
查找步骤
- 遍历待查找的数组/列表,从索引
0(第一个元素)开始; - 每遍历一个元素,就和目标值做比较;
- 若相等,返回该元素的索引(表示找到);
- 若遍历完所有元素仍未找到,返回一个特殊值(如
-1)表示查找失败。
适用场景
线性查找适合小数据量(且无序)的查找场景,比如列表长度小于100;
如果是大数据量(万级/百万级) 且数据有序,建议使用二分查找(效率远高于线性查找);
例子
给定一个无序的数字序列:[7, 2, 9, 4, 1, 8],要找数字 4,用顺序查找的步骤:
- 检查第 1 个数字 7 → 不是 4,继续;
- 检查第 2 个数字 2 → 不是 4,继续;
- 检查第 3 个数字 9 → 不是 4,继续;
- 检查第 4 个数字 4 → 找到目标,停止查找。
如果要找数字 5,就会依次检查完 6 个数字(7→2→9→4→1→8),最终确定序列里 没有 5
优缺点
优点
- 实现简单:无需复杂逻辑,新手易理解、易编写;
- 无数据要求:待查找的列表 无需排序,有序/无序都能查;
- 数据结构友好:适配数组、链表等几乎所有线性数据结构;
- 支持提前终止:找到目标值后立即返回,无需遍历全部元素。
缺点
- 效率较低:最坏情况下需要遍历全部元素(目标值在最后/不存在),时间复杂度高。
查找速度
最好情况
O(1),目标值是列表第一个元素,一次比较就找到;
最坏情况
O(n),n是列表长度,目标值在最后/不存在,需要n次比较;
平均情况
推导过程:
- 目标在第 1 位:需要 1 次比较
- 目标在第 2 位:需要 2 次比较
- …
- 目标在第n位:需要 n 次比较,概率n
\frac{1 + 2 + 3 + \ldots + n } { n}
提示: 除以 n 是因为计算平均情况
因为 1 + 2 + 3 + \ldots + n = n*(1+n)/2 ,所以
\frac{(1 + n ) * n} { 2 * n}
约掉n,最后结果:
\frac{ 1 + n} {2}
时间复杂度
最好情况
O(1),目标值是列表第一个元素,一次比较就找到;
最坏情况
O(n),n是列表长度,目标值在最后/不存在,需要n次比较;
平均情况
由 查找速度-平均情况可知,平均情况是: \frac{ 1 + n} {2}
用 大O表示法,也就是:O(n)
空间复杂度
O(1),仅使用了少量临时变量(索引、目标值),无需额外开辟内存空间,属于原地查找。
实现
java
public class LinearSearchBasic {
public static int linearSearch(int[] arr, int target) {
// 判空,避免空指针异常(工程开发必备)
if (arr == null) {
return -1;
}
int n = arr.length; // 提取数组长度,避免多次调用arr.length
// 从索引0遍历到n-1
for (int i = 0; i < n; i++) {
if (arr[i] == target) {
return i; // 找到目标,立即返回索引(提前终止)
}
}
return -1;
}
// 测试
public static void main(String[] args) {
// 测试用例1:包含目标值
int[] numArr1 = {5, 2, 9, 1, 5, 6};
int target1 = 9;
System.out.println("目标值" + target1 + "的索引:" + linearSearch(numArr1, target1)); // 输出:2
// 测试用例2:不包含目标值
int target2 = 3;
System.out.println("目标值" + target2 + "的索引:" + linearSearch(numArr1, target2)); // 输出:-1
// 测试用例3:空数组
int[] numArr2 = {};
System.out.println("空数组查找结果:" + linearSearch(numArr2, 5)); // 输出:-1
}
}
python
# 线性查找核心函数
# 参数:arr-待查找的列表,target-要找的目标值
# 返回:找到则返回目标值的索引,未找到返回-1
def linear_search_basic(arr, target):
n = len(arr) # 获取列表长度
for i in range(n): # 从索引0遍历到n-1
if arr[i] == target: # 找到目标值,立即返回索引
return i
return -1 # 遍历结束未找到,返回-1
# 测试代码
if __name__ == "__main__":
# 测试用例1:数字列表(包含目标值)
num_list = [5, 2, 9, 1, 5, 6]
target1 = 9
print(f"目标值{target1}的索引:{linear_search(num_list, target1)}") # 输出:2
# 测试用例2:数字列表(不包含目标值)
target2 = 3
print(f"目标值{target2}的索引:{linear_search(num_list, target2)}") # 输出:-1
# 测试用例3:字符串列表
str_list = ["Python", "Java", "C", "JavaScript"]
target3 = "C"
print(f"目标值{target3}的索引:{linear_search(str_list, target3)}") # 输出:2