c++数组的折半查找和线性查找

线性查找:

线性查找(Linear Search)是一种简单的查找技术,用于在列表、数组或其他线性数据结构中查找一个特定的元素。线性查找的基本思想是从数据结构的一端开始,逐个检查每个元素,直到找到所需的元素或搜索完整个数据结构为止。

线性查找步骤:

1.从数据结构的一端开始:通常是从第一个元素开始。
2.逐个检查元素:将当前元素与目标元素进行比较。
3.如果找到目标元素:则返回该元素的位置(或该元素的引用、值等,取决于具体的应用场景)。
4.如果当前元素不是目标元素:则继续检查下一个元素。
5.重复步骤2-4:直到找到目标元素或检查完所有元素。
6.如果未找到目标元素:则根据具体的应用场景,可能返回一个错误码、空值或-1等,表示未找到目标元素,一般来说返回-1.

线性查找代码:

#include <iostream>
using namespace std;
int LinearSearch(const int AA[],int key,int SizeofAA){
//const int AA[]表示AA[]数组是一个整型的常量数组,key表示查找的数值,SizeofAA表示元素个数 
	for(int i=0;i<SizeofAA;i++){
		if(key==AA[i])
			return i; //返回索引 
	}
	return -1;//索引>=0,而返回-1表示key不在数组中,用于主函数的判断 
}
int main(){
	int aSize=10;//数组的元素个数
	int A[aSize]={1,3,9,2,4,5,6,7,11,88};
	int Searchkey;
	cout <<"请输入要查找的值:"<<endl;
	cin >>Searchkey;
	int b=LinearSearch(A,Searchkey,aSize);
	if(b==-1){
		cout <<"该数不在数组中,查找失败"<<endl;
	} 
	else{
		cout<<"该数在数组中,索引下标为:"<<b<<"  查找成功"<<endl;
	}
	return 0;
} 

线性查找复杂度:

  • 时间复杂度:在最坏的情况下(即目标元素不在数据结构中或位于数据结构的末尾),需要检查所有的元素,因此时间复杂度为O(n),其中n是数据结构中元素的数量。在最好的情况下(即目标元素是数据结构的第一个元素),时间复杂度为O(1)。然而,由于我们不能预测目标元素的位置,因此通常考虑最坏情况的时间复杂度。
  • 空间复杂度:线性查找不需要额外的存储空间(除了几个用于循环和比较的变量外),因此空间复杂度为O(1)。

折半查找:

折半查找(Binary Search),也被称为二分查找,是一种在有序数组中查找特定元素的搜索算法。其基本原理是通过将待查找的区间分成两半,判断待查找的元素可能在哪一半,然后继续在可能存在该元素的那一半区间内查找,以此逐步缩小查找范围,直到找到该元素或确定该元素不存在。

折半查找步骤 :

确定查找范围:首先,确定整个数组作为查找范围,即定义两个指针(或索引)lowhigh,分别指向数组的第一个元素和最后一个元素。

计算中间位置:计算lowhigh中间位置的索引mid,可以使用(low + high) / 2low + (high - low) / 2来避免可能的整数溢出问题。

比较中间元素:将中间位置的元素与待查找的元素(称为key)进行比较。

如果相等,则查找成功,返回中间位置的索引。如果key小于中间位置的元素,说明待查找的元素只可能出现在左半部分,因此将high更新为mid - 1,继续在左半部分查找。如果key大于中间位置的元素,说明待查找的元素只可能出现在右半部分,因此将low更新为mid + 1,继续在右半部分查找。

缩小查找范围:重复步骤2和步骤3,直到找到元素或low大于high(说明元素不存在于数组中)。

返回结果:如果找到元素,则返回其索引;如果未找到,则通常返回某个特殊值(如-1)表示查找失败。

折半查找代码:

#include <iostream>  
#include <vector>  
using namespace std;  
  
// 二分查找函数,返回目标值在数组中的索引,如果未找到则返回-1  
int binarySearch(const vector<int>& arr, int target) {  
    int left = 0; // 查找范围的左边界  
    int right = arr.size() - 1; // 查找范围的右边界  
  
    while (left <= right) {  
        // 防止(left + right)直接相加导致的溢出,同时计算中间索引  
        int mid = left + (right - left) / 2;  
  
        if (arr[mid] == target) {  
            // 找到目标值,返回索引  
            return mid;  
        } else if (arr[mid] < target) {  
            // 目标值在右半部分,调整左边界  
            left = mid + 1;  
        } else {  
            // 目标值在左半部分,调整右边界  
            right = mid - 1;  
        }  
    }  
  
    // 未找到目标值,返回-1  
    return -1;  
}  
  
int main() {  
    int tempArray[] = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19}; // 使用数组初始化 ,已经从小到大排序完成的数组 
    vector<int> arr(tempArray, tempArray + sizeof(tempArray) / sizeof(tempArray[0])); // 从数组初始化vector  
    int target ; // 要查找的目标值  
  	cout <<"请输入需要查找的值:"<<endl;
	cin>>target; 
  	
    int result = binarySearch(arr, target);  
  
    if (result != -1) {  
        cout << "元素 " << target << " 找到,索引为:" << result << endl;  
    } else {  
        cout << "元素 " << target << " 未找到" << endl;  
    }  
  
    return 0;  
}

 折半查找复杂度:

时间复杂度

  • 最好情况:当目标值正好是数组的中间元素时,算法只需要一次比较就能找到目标值,此时的时间复杂度为 O(1)。但是,由于这种情况并不常见,且依赖于目标值的具体位置,因此在分析折半查找的复杂度时通常不考虑最好情况。

  • 最坏情况:当目标值不存在于数组中,或者目标值位于数组的第一个或最后一个位置(并且数组很大,使得每次查找都需要遍历到另一端),算法需要进行 log₂(n) + 1 次比较(其中 n 是数组的长度,因为算法是向下取整,所以实际比较次数可能比 log₂(n) 多一次)。因此,最坏情况下的时间复杂度是 O(log n)。

  • 平均情况:由于每次查找都会将搜索范围减半,平均情况下也需要进行大约 log₂(n) 次比较。因此,平均情况下的时间复杂度也是 O(log n)。

空间复杂度

折半查找算法的空间复杂度是 O(1)。这是因为算法在查找过程中只需要维护几个指针或索(如左边界 left、右边界 right 和中间位置 mid),这些都不随输入规模 n 的增长而增长。算法没有使用额外的数据结构来存储中间结果,因此空间复杂度是常数级别的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值