知识点
- 命名空间
C++标准程序库中的所有标识符都被定义于一个名为std的namespace中。
因为标准库非常的庞大,所以程序员在选择的类的名称或函数名时就很有可能和标准库中的某个名字相同。
所以为了避免这种情况所造成的名字冲突,就把标准库中的一切都放在名字空间std中。
namespace允许像类,对象,函数聚集在一个名字下。本质上讲namespace是对全局作用域的细分。
但这有会带来了一个新问题。无数原有的C++代码都依赖于使用了多年的伪标准库中的功能,他们都是在全局空间下的,所以就有了
<
i
o
s
t
r
e
a
m
>
<iostream>
<iostream>和<iostream.h>等等这样的头文件,一个是为了兼容以前的C++代码,一个是为了支持新的标准。
命名空间std封装的是标准程序库的名称,标准程序库为了和以前的头文件区别,一般都不加".h"。
using namespace std;
- 类对象的实例化
声明类的对象
Class1 Obj1; Obj1: 是类Class1的对象 , 类
- vector 数组的 初始化;
vector<int> data = {1,2, 3, 4, 5};
1. 二分查找的前提
- 给定数组是有序数组
- 数组中无重复元素(有重复元素时, 返回的下标不唯一)
- 根据右区间的开闭,写出两种不同的二分查找;
1.1 右区间关闭
根据右区间关闭这个特点 , [left, right ];
所以有如下两点:
- 因为右区间值,可以取到,所以有 while(left <= right): left == right 是有意义的;
- if (nums[middle] > target ): right = middle -1, 因为此时 nums[middle] 一定不是 target, 所有将右区间的下标位置移动到 middle -1;
#include <vector>
#include <iostream>
using namespace std;
class Solution{
public:
int search(vector<int>& nums, int target ){
int left = 0;
int right = nums.size() - 1; //这里使用右区间关闭, 故右区间值取得到;
while ( left <= right){ // 因为右区间取得到, 所以 <= 是有意义的;
int middle = left + (right - left )/2 ;
if (nums[middle] > target){ // 中间值大于目标值, 说明目标值在左侧, 则应该将 右区间往左移动;
right = middle - 1 ; // 因为此时, nums[middle] 一定不是 target;
} else if(nums[middle] < target){
left = middle + 1;
} else {
return middle;
}
}
return -1;
}
};
int main(){
// int arr[6] = {-1,0,3,5,9,12};
vector<int> nums1 ={-1,0,3,5,9,12};
int target = 12;
Solution obj1;
int middle = obj1.search(nums1, target);
cout << middle << endl;
}
1.2 右区间开, 右端点取不到
根据右区间关闭这个特点 , [left, right );
有如下两点:
- while (left < right),这里使用 < ,因为left == right在区间[left, right)是没有意义的
- if (nums[middle] > target) right 更新为 middle,因为当前nums[middle]不等于target,去左区间继续寻找,而寻找区间是左闭右开区间,所以right更新为middle,即:下一个查询区间不会去比较nums[middle]
class Solution {
public:
int search(vector<int>& nums, int target){
int left = 0;
int right = nums.size() ; // 注意,因为是右开区间, 右侧端点取不到;
while (left < right){ // 因为右侧端点取不到, 所以是 取不到等号
int middle = (left + right ) / 2;
if (nums[middle] > target){
right = middle; // 中间值 大于target, 说明区间往左移动, right 取值middle, 因为此时右端点是开区间;
}else if (nums[middle] < target){
left = middle + 1 ; // 因为 此时 nums[middle] 不是target, 且 left端点值可以取到, 所以 left = middle + 1
}else{
return middle;
}
}
return -1;
}
};