旋转数组的二分法查找

/*
	一数组, array [] = {1,2,3,4,5,6,7,8,9};
	从某一位置开始旋转,变为以下数组
	array_ex[] = {6,7,8,9,1,2,3,4,5};
	现在给定一个数值x,查找x是否在该数组array_ex中
	算法思想:1.如果数组为有序数组,没有移位的话,则直接用二分法查找即可
	2.如果有移位的话,则满足arr[left] >= arr[right].出现这样的情况,不能直接判断数值是否在该序列中,
	应该继续划分。 mid = (left + right)/2. 利用[left,mid]和[mid, right)继续1步骤,如果其中一个分组
	满足步骤1的话,就不需要再继续2步骤
*/


#include<iostream>
using namespace std;

bool find_data(int*arr , int left, int right, int data, int& loop_cnt)
{
	loop_cnt = 0x00;
	if(arr[left] >= arr[right])
	{
		bool b_stop = false;
		int mid = 0x00;
		while(!b_stop && left < right)
		{
			loop_cnt++;
			mid = (left + right) / 0x02;
			
			//防止死循环。主要是因为[left,right]为非有序空间的时候,循环的时候不能使
			//left=mid+1或right=mid-1
			if((right - left) <= 0x01)
			{
				if(arr[left] != data && arr[right] != data)
				{
					b_stop = true;
					continue;
				}
			}
			
			if(arr[left] <= arr[mid])
			{
				//查找到data可能所在的序列空间
				if(arr[left] <= data && arr[mid] >= data)
				{
					right = mid;
					b_stop = true;
				}
				else
				{
					left = mid;
				}
			}
			else if(arr[mid] <= arr[right])
			{
				//查找到data可能所在的序列空间
				if(arr[mid] <= data && arr[right] >= data)
				{
					left = mid;
					b_stop = true;
				}
				else
					right = mid;
			}
		}
	}
	
	//执行到这里,[left,right]或为有序空间,或不存在
	if(arr[left] > data || arr[right] < data)
		return false;
		
	//使用二分法查找数据
	while(left <= right)
	{
		loop_cnt++;
		int mid = (left + right) / 0x02 ;
		if(arr[mid] == data)
			return true;
			
		if(arr[mid] > data)
			right = mid - 0x01;
		else 
			left = mid + 0x01;
	}
	return false;
}

void show_array(int* arr, int len)
{
	for(int index = 0x00; index < len; index++)
		std::cout<<arr[index]<<" ";
	std::cout<<std::endl;
}

int main()
{
	int array[100] = {0x00};
	int lp_index = 0x00;
	for(int index = 30; index < 100; index++)
	{
		array[lp_index++] = index;
	}
	for(int index = 0x00; index < 30; index++)
	{
		array[lp_index++] = index;
	}
	show_array(array,100);
	for( int index = 0x00; index < 200; index += 5)
	{
		int loop_cnt = 0x00;
		bool ret = find_data(array, 0x00, 99, index,loop_cnt);
		if(ret)
			std::cout<<" find data "<<index<<" ok . loop_cnt is :"<<loop_cnt<<std::endl;
		else
			std::cout<<" find data "<<index<<" failed. loop_cnt is :"<<loop_cnt<<std::endl;
	
	}
	return 0x00;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值