哨兵线性搜索
顾名思义,哨兵线性搜索是线性搜索的一种,与传统线性搜索相比,比较次数减少了。在传统的线性搜索中,仅进行N次比较,而在哨兵线性搜索中,哨兵值用于避免任何越界比较,但没有专门针对正在搜索的元素的索引进行额外的比较。
在这种搜索中,将数组的最后一个元素替换为要搜索的元素,然后对数组进行线性搜索,而不检查当前索引是否在数组的索引范围内,因为要搜索的元素即使它不存在于原始数组中,也肯定会在数组中找到,因为最后一个元素被替换为它。因此,要检查的索引永远不会超出数组的范围。最坏情况下的比较次数将为(N+2)。
哨兵线性搜索是标准线性搜索算法的变体,用于在数组或列表中查找目标值。该算法背后的基本思想是在数组末尾添加一个标记值,该值等于我们正在查找的目标值。这有助于避免在循环的每次迭代期间检查数组边界条件,因为哨兵值充当循环的停止器。
尽管在最坏情况下时间复杂度这两种算法都是 O(n)。只是哨兵线性搜索比线性搜索少了比较次数
使用哨兵线性搜索:
在搜索数组中的元素时,哨兵线性搜索是线性搜索算法的变体,它使用哨兵值来优化搜索过程。
哨兵线性搜索的基本思想是在数组末尾添加一个与搜索键匹配的额外元素(即哨兵值)。通过这样做,我们可以避免在循环中对数组末尾进行条件检查,并在找到哨兵元素后尽早终止搜索。这消除了对数组末尾进行单独检查的需要,从而使算法的平均情况性能略有提高。
Sentinel线性搜索算法的步骤如下:
将搜索索引变量 i 初始化为 0。
将数组的最后一个元素设置为搜索键。
当搜索键不等于数组的当前元素(即 arr[i])时,增加搜索索引 i。
如果 i 小于数组大小或 arr[i] 等于搜索键,则返回 i 的值(即搜索键在数组中的索引)。
否则,搜索键不存在于数组中,因此返回 -1(或任何其他适当的值来指示未找到该键)。
Sentinel 线性搜索算法的主要好处是它不需要单独检查数组末尾,这可以提高算法的平均情况性能。然而,它并没有改善最坏情况下的性能,仍然是 O(n)(其中 n 是数组的大小),因为我们可能需要扫描整个数组才能找到哨兵值。
例子:
输入: arr[] = {10, 20, 180, 30, 60, 50, 110, 100, 70}, x = 180 输出
: 180 出现在索引 2
输入: arr[] = {10, 20, 180, 30, 60, 50, 110, 100, 70}, x = 90
输出:未找到
// C++ implementation of the approach
#include <iostream>
using namespace std;
// Function to search x in the given array
void sentinelSearch(int arr[], int n, int key)
{
// Last element of the array
int last = arr[n - 1];
// Element to be searched is
// placed at the last index
arr[n - 1] = key;
int i = 0;
while (arr[i] != key)
i++;
// Put the last element back
arr[n - 1] = last;
if ((i < n - 1) || (arr[n - 1] == key))
cout << key << " is present at index " << i;
else
cout << "Element Not found";
}
// Driver code
int main()
{
int arr[] = { 10, 20, 180, 30, 60, 50, 110, 100, 70 };
int n = sizeof(arr) / sizeof(arr[0]);
int key = 180;
sentinelSearch(arr, n, key);
return 0;
}
// This code is contributed by Mandeep Dalavi
输出
180当前的索引 2