关于二分查找大家都挺熟悉的,今天主要是给大家讲一下二分查找衍生出来的一系列问题
首先给呈上二分查找的代码实现
//返回目标数字的下标
//val:查找的数字
int SearchValue(const vector<int> &vec,const int val)
{
int right=vec.size()-1;
int left=0;
int mid;
while(right>=left)
{
mid=(right-left)/2+left;
if(val>vec[mid])
{
left=mid+1;
}
if(val<vec[mid])
{
right=mid-1;
}
if(val==vec[mid])
{
return mid;
}
}
return -1;
}
然后我们就开始解决二分查找衍生出来的问题
问题一:使用vector容器有什么好处?为什么不用数组?
回答:数组是一个固定的大小,存放的数据个数是一个不确定因素;哪怕动态开辟也要先获取大小。而vector会自动开辟存放数据的空间,这是的一个优势。还有就是新插入元素时vector有push_back()这个接口可以往容器里放元素。数组则没有这样的接口。再者就是数组缺乏vector容器的size()接口,不方便遍历。
问题二: 如果数据有重复,如何找到最left 端的数据?
回答:如果数据有重复的话我们优化一下代码,把上述代码种if(val==vec[mid])部分改一下
if(val==vec[mid])
{
int i;
for(i=mid-1;i>=0;i--)//从找到的位置往左遍历
{
if(vec[i]==val)//如果前一个和目标数相同那就继续往前
continue;
break;
}
return i+1;//返回下标
}
问题四:如果是无序的怎么办?
回答:用快排使数组有序,然后就行二分查找。
问题五:编写快排
void quick(vector<int> &arr,int left,int right)
{
if(left>right)
{
return;
}
int i=left;
int j=right;
int n=arr[left];//确定基准数
while(i!=j)
{
while(n<=arr[j]&&i<j)
j--;
while(n>=arr[i]&&i<j)
i++;
if(i<j)
{
swap(arr[i],arr[j]);
}
}
swap(arr[i],arr[left]);
quick(arr,left,i-1);
quick(arr,i+1,right);
}