使用二分法求解

给定一个排好升序的数组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;
}

测试结果:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值