哨兵线性搜索算法浅析与Python,C#实践Demo
如题:
在数组A[]
中搜索给定值foundNum
,其中length是A[]的长度
- 常规线性搜索
1.令索引i初始值为0,按次序依次赋值到n-1;
(a)如果A[i]==foundNum,返回当前i;
2.返回-1;代表没找到
在常规线性搜索的第1步实际有两个测试:一个是判断索引是否越界,二是判断是否与foundNum相等。也就是在遍历的时候,实际上每次都要判断一次是否越界。
- 哨兵线性搜索
针对常规线性搜索的每次都要判断越界的这个操作,我们可进行如下优化,首先将A[]
的最后一个元素改成foundNum,那么就“确保肯定能搜到”foundNum
值了,下面就可以只判断是否当前值与foundNum相等,如果不等,就“无脑”增加索引值,而避开了判断索引是否越界的这个操作,那么,还有个问题,就是万一最后一个值恰好就是foundNum,该如何处理,很简单,现在就只需要一次判断最后一个值 是否就是foundNum就可以了。最后根据i<n-1或者A[n-1]==foundNum来给出结果,如果这两个条件都不满足,那么就返回-1,代表没找到。
1.将A[length-1]的值保存在last中,令A[length-1]=foundNum;
2.i赋值为0;
3.只要A[i]!=foundNum,就自增i;
4.否则,A[length-1]重新赋值为last
5.如果i<length-1 或者A[length-1]==foundNum,返回i
否则,返回-1,代表没找到
C#代码进行验证:
class Program
{
public static void Main()
{
long max = 1000000000;
int result;
long[] a = new long[max];
for(long i = 0; i < a.Length; i++)
{
a[i] = i;
}
var stpw = new Stopwatch();
stpw.Start();
result=BetterLinearSearch(a,a.Length, max);
stpw.Stop();
Console.WriteLine("BetterLinearSearch result:{0},time:{1}", result, stpw.ElapsedMilliseconds);
var stpw0 = new Stopwatch();
stpw0.Start();
result = SentinelLinearSearch(a,a.Length, max);
stpw0.Stop();
Console.WriteLine("SentinelLinearSearch result:{0},time:{1}", result, stpw0.ElapsedMilliseconds);
}
public static int BetterLinearSearch(long[] a,int length,long foundNum)
{
for(int i = 0; i < length; i++)
{
if (a[i] == foundNum) return i;
}
return -1;
}
public static int SentinelLinearSearch(long[] a,int length,long foundNum)
{
var last = a[length-1];
a[length-1] = foundNum;
int i = 0;
do
{
if (a[i] != foundNum)
{
i += 1;
}
else
{
a[length-1] = last;
if (i < length-1 || a[length-1] == foundNum) return i;
else return -1;
}
}
while (true);
}
}
python代码进行实践:
import time
max=100000000
a=list(range(max))
def linearSearch(a,num,findNum):
i=0
while(i<len(a)): #不用 for i in range(len(a)) 是因为python中的for并没有索引递增
#然后判断是否越界,而是直接在容器/迭代器中进行遍历
if(a[i]==findNum):
return i;
else:
i+=1;
return -1;
def sentinelLineSearch(a,num,findNum):
last=a[-1]
a[-1]=findNum
i=0
while(True):
if(a[i]!=findNum):
i+=1
else:
a[-1]=last
if(i<(num-1) or a[num-1]==findNum):
return i
else:
return -1
tim=time.time()
b=linearSearch(a,len(a),len(a))
print("LinearSearch result is {0}, time is {1}".format(b,time.time()-tim))
tim=time.time()
b=sentinelLineSearch(a,len(a),len(a))
print("SentinelLinearSearch result is {0},time is {1}".format(b,time.time()-tim))
实际代码也确实验证了哨兵线性搜索算法比常规线性搜索算法更高效些。
#####
愿你一寸一寸地攻城略地,一点一点地焕然一新
#####
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix