实现如下函数,查找一个“两段有序”的整数数组a中是否存在某个整数x,返回对应的数组下标

题目描述:

请实现如下函数,查找一个“两段有序”的整数数组a中是否存在某个整数x,返回对应的数组下标。算法复杂度O(log2(n))注:“两段有序”的数组定义如下,将一个有序的数组从某个位置分成两段(分界点未知),然后把后面一段放在前、前面一段放在后 拼成一个新的数组,即为“两段有序”,示例如下:

原有序数组

4

7

9

10

24

35

65

73

88

90

从73分成两段,重新组成一个新的“两段有序”数组

73

88

90

4

7

9

10

24

35

65

解题思路:

1、像二分查找一样,取中间值,如果中间值同时小于等于两边的值,则可以将数组分为两段,数组的左段(left ----mid)为“两段有序“数组,右段(mid----right)为一个有序数组

       接下来再判断待查找值,再右端还是左段,如果待查找值大于mid 小于right值(即在右段),则在有序数组中,则用二分查找 即可。

       否则,将right = mid - 1重复即可。

2、如果中间值同时大于等于两边值,则可以将数组也分为两段,左段(left --- mid)为一个有序数组,而有段(mid----right)为一个”两段有序“数组。

      接下来再判断待查找值,再右端还是左段,如果待查找值小于mid 大于left值(即在左段),则在有序数组中,则用二分查找 即可。

      否则,将left = mid + 1重复即可。

至此:题目已解决。

源代码

//二分查找
int binary_search(int elems[], int left, int right,int x)
{
	while (left <= right)
	{
		int mid = (right - left) / 2 + left;
		if (elems[mid] == x)
		{
			return mid;
		}
		else if (elems[mid] < x)
		{
			left = mid + 1;
		}
		else
		{
			right = mid - 1;
		}
	}
	return -1;
}



int search(int *elems, int size, int x) {
	int left = 0;
	int right = size - 1;

	while (left <= right)
	{
		int mid = (right - left) / 2 + left;
		
		if (x == elems[mid] || x == elems[left] || x == elems[right])
		{
			if (x == elems[mid])
			{
				return mid;
			}
			return (x==elems[left] ? left : right);
		}


		//同时小于mid的右边是有序数组
		if (elems[mid] <= elems[right] && elems[mid] <= elems[left])
		{
			//如果判断x在mid的右边 大于mid 小于right
			if (elems[mid] < x && elems[right] > x)
			{
				//二分查找
				return binary_search(elems, left, right ,x);
			}
			else//在“两段有序”数组的区间
			{
				right = mid - 1;
			}
		}
		//同时大于mid的左边是有序
		else if(elems[mid] >= elems[right] && elems[mid] >= elems[left])
		{
			//如何判断x在mid的右边小于mid 小于left
			if (elems[mid] > x && elems[left] < x)
			{
				//二分查找
				return binary_search(elems,left,right,x);
			}
			else//在”两段有序数组“数组区间
			{
				left = mid + 1;
			}
		}
		
	}

	return - 1;
}



int main()
{

	int elems[] = {73,88,90,4,7,9,10,24,35,65,67};

	for (int i = 0; i < 11; i++)
		cout << search(elems, 11, elems[i]) << endl;

	
	system("pause");
	return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值