下面要讲述的是两种用到折半查找的定位需求
定位一
tips: 辅助快速插入,找到某个数对应的插入位置。
细节描述:在一个有序数组list中,插入一个数num.
插入一个num,先要找到插入的位置,一般情况下折半查找的速度是最快的。
在list数组中,需要找到一个位置 i,满足
(
l
i
s
t
[
i
−
1
]
<
=
n
u
m
)
&
&
(
l
i
s
t
[
i
]
>
n
u
m
)
(list[i-1]<=num )\&\& (list[i]>num)
(list[i−1]<=num)&&(list[i]>num)
i就是num要插入的位置即插入完成后
l
i
s
t
[
i
]
=
=
n
u
m
list[i]==num
list[i]==num
public int findInsertLoc(List<Integer> a, int n)
{
int l=-1,r=a.size();
while(l<r-1)
{
int mid = (l+r)>>1;
int v = a.get(mid);
if(v<n)
l=mid;
else if(v>n)
r=mid;
else
{
l=mid;
r=l;
}
}
/*循环结束以后
*如果n小于a中所有的数 l=-1;
*如果n大于a中所有的数 l=a.size()-1;
*其他情况都满足 a.get(l)<=n && a.get(l+1)>n
*最后 l+1的位置就是n要插入的位置
*/
return l+1;
}
定位二
细节描述:查找顺序数组list中元素e的位置,若不存在返回-1;
想法:在上一种定位的描述中可以知道位置i,是一个特殊的位置,满足
(
l
i
s
t
[
i
−
1
]
<
=
n
u
m
)
&
&
(
l
i
s
t
[
i
]
>
n
u
m
)
(list[i-1]<=num )\&\& (list[i]>num)
(list[i−1]<=num)&&(list[i]>num)
所以要找到e的位置只要通过findInsertLoc()方法找到位置i,且
(
i
!
=
0
)
&
&
(
l
i
s
t
[
i
−
1
]
=
=
e
)
(i!=0)\&\&(list[i-1]==e)
(i!=0)&&(list[i−1]==e)
则e在list中的位置就是i-1.
否则e就不在list中.