使用二分法求解

来源:互联网 发布:怎么做图书marc数据 编辑:程序博客网 时间:2024/05/01 11:59

给定一个排好升序的数组A[1]、A[2]、……、A[n],其元素的值都两两不相等。请设计一高效的算法找出中间所有A[i] = i的下标。并分析其复杂度。

思路:

假设数组长度为len,则数组第一个元素的下标为0,最后一个元素的下标为len-1

1、当数组中第一个元素A[0]大于len-1时,因为数组中元素是升序,所以数组中其他元素都比len-1大。这种情况下A[i]不可能等于i。

2、当数组中最后一个元素A[len-1]小于0时,因为数组中元素是升序,所以数组中其他元素都比0小。这种情况下A[i]不可能等于i。

只有序列A[0]到A[len-1]与序列0到len-1有重叠部分时,A[i]才有可能等于i。

开始时left=0,right=len-1;

med=(left+right)/2;

判断A[med]==med;

zai

查找函数:

#include<iostream>using namespace std;typedef double ElemType;void find(ElemType *arr,int left,int right ){if(right<left||arr==NULL)//当右下标小于左下标,函数返回。return;if(arr[right]<left||arr[left]>right)//当数组最后一个值小于左下标//或者数组最后一个值大于右下标。//函数返回。return ;int med=(left+right)/2;if(arr[med]==med)cout<<med<<" ";find(arr,left,med-1);//递归左边区域find(arr,med+1,right);//递归右边区域}
测试用例及输出数组元素函数:

void print(ElemType * arr,int len){for(int i=0;i<len;i++)cout<<arr[i]<<" ";cout<<endl;}


void test1(){cout<<"test1"<<endl;ElemType arr[]={0};int len=sizeof(arr)/sizeof(arr[0]);print(arr,len);find(arr,0,len-1);cout<<endl;}void test2(){cout<<"test2"<<endl;ElemType arr[]={1};int len=sizeof(arr)/sizeof(arr[0]);print(arr,len);find(arr,0,len-1);cout<<endl;}void test3(){cout<<"test3"<<endl;ElemType arr[]={1,2,3,4,5,6};int len=sizeof(arr)/sizeof(arr[0]);print(arr,len);find(arr,0,len-1);cout<<endl;}void test4(){cout<<"test4"<<endl;ElemType arr[]={0,1,3,4,5,7};int len=sizeof(arr)/sizeof(arr[0]);print(arr,len);find(arr,0,len-1);cout<<endl;}void test5(){cout<<"test5"<<endl;ElemType arr[]={0,1,2,3.6,4.5,5};int len=sizeof(arr)/sizeof(arr[0]);print(arr,len);find(arr,0,len-1);cout<<endl;}

主函数:

int main(){//ElemType arr[6]={0,1,3,3.8,4.9,5}; //ElemType arr[] = {0, 1};     //ElemType arr[] = {0, 1, 2, 3, 4, 5, 6, 7};     //ElemType arr[] = {-9, -8, -4, -2, 4, 5, 9};     test1();test2();test3();test4();test5();return 0;}

测试结果:



0 0