首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

怎么快速确定某整数是否在一个被顺序移位的有序整数数组中

2012-05-30 
如何快速确定某整数是否在一个被顺序移位的有序整数数组中RT[解决办法]被顺序移位?什么意思?如果是简单有

如何快速确定某整数是否在一个被顺序移位的有序整数数组中
RT

[解决办法]
被顺序移位?什么意思?
如果是简单有序二分查找即可
[解决办法]
用折半查找
[解决办法]
是每个数字都以为还是什么??不明白。
[解决办法]
那得要给出最大值所在位置才能快速查找。
[解决办法]
将数组内容进行移位,使其递增排序,然后使用折半查找。
[解决办法]
确定最小数和最大数的位置,min_pos,max_pos,然后获得长度len
那么mid_pos=(min_pos+max_pos+len)/2,说白了就是二分查找
[解决办法]
先找到最大的位置,当他是个循环队列,然后二分就可以了
[解决办法]

探讨

确定最小数和最大数的位置,min_pos,max_pos,然后获得长度len
那么mid_pos=(min_pos+max_pos+len)/2,说白了就是二分查找

[解决办法]
既然数组是有个有序数组,那么除了数组的首地址p和长度len外,还需要一个参数指定最小整数的位置pos,则数组可分为2子数组,第一个子数组是a[0]..a[pos-1], 第二个子数组a[pos]..a[len-1]。分别在2个子数组中做2分查找即可。

如果不知道最小元素的位置,先做个顺序查找,可找到最小元素的位置,时间复杂度为O(len),二分查找的时间复杂度为O(log2(len))
[解决办法]
用改进的折半查找吧,大概写了一个
if(elem>=a[0])
{
int left=0,right=size-1;
int mid=left+(right-left)/2;
while(left<right)
{
mid=left+(right-left)/2;
if(a[mid]==elem)
{
return mid;
}
else
{
if(a[mid]<elem)
{
if(a[mid]<a[left])
{
right=mid-1;
}
else
{
left=mid+1;
}
}
else
{
right=mid-1;
}
}
}
return -1;
}
else
{
int left=0,right=size-1;
int mid=left+(right-left)/2;
while(left<right)
{
mid=left+(right-left)/2;
if(a[mid]==elem)
{
return mid;
}
else
{
if(elem<a[mid])
{
if(a[mid]<a[right])
{
right=mid-1;
}
else
{
left=mid+1;
}
}
else
{
left=mid+1;
}
}
}
return -1;
}
[解决办法]
探讨

用改进的折半查找吧,大概写了一个
if(elem>=a[0])
{
int left=0,right=size-1;
int mid=left+(right-left)/2;
while(left<right)
{
mid=left+(right-left)/2;
if(a[mid]==elem)
{
return mid;
}
else
{
if(a[mid]<el……

[解决办法]
探讨

移位恢复成完全有序,折半
找到分界点,折半

这两种其实差不多,也是大家第一眼就能想到的,但是我觉得这种问题是不是有一种更优雅、更奇特的方式解决?

[解决办法]
抱歉,这样的解法只能用在特殊场合,不具普适性。

比如你说这个问题,就是因为只有一个出线单数次。xor运算的特点就是同一数值经过双数次运算后结果会为零,最终只有那个单数次出现的家伙被保留下来。如果出现单数次的不止一个,则该算法无用。

你在顶楼所提状况就没有这样的特殊规律可供使用了。如果一定要说有,那就是原本是个有序数组,经循环移位后仍旧保持局部有序的特性。不过这个特性已经被折半查找利用过了,否则就只能靠遍历寻找了。
[解决办法]
首先用二分法查找“分界点”,然后对分成的两部分,分别用二分法查找。
总共是O(log(n))复杂度。

C/C++ code
// 数组x是有序数组循环移位,数组长度len必需大于1// 找到一个位置pos,这个位置的数大于等于x[0],这个数下一个小于等于x[len-1]// 结果:[0,pos]之间的数是有序的,[pos,len-1]之间的数是有序的int  max_pos( int *x, int len ) {    int  beg = 0, end = len - 1;    int  left = x[0], right = x[len-1];    while( beg <= end ) {        int  mid = ( beg + end ) / 2;        if( x[mid] < left ) end = mid - 1;        else if( x[mid+1] > right ) beg = mid + 1;        else return mid;    }    return  -1;} 

热点排行
Bad Request.