您的位置:首页 > 编程语言

3.11 程序改错(二分查找)

2016-06-03 20:23 369 查看

问题:

找出一个有序(字典序)字符串数组中arr中值等于字符串v的元素的序号,如果有多个元素满足这个条件,则返回其中序号最大的。

分析:

二分查找的细节确实很多啊。~~(╯﹏╰)b

我就不实现这个问题了。我主要实现后面几个小题。

给定一个有序(不降序)数组arr,求最大的i使得arr[i]等于v,不存在则返回-1。

我自己写的时候,跟书上犯了一模一样的错误…..

int bisearch_findMaxIdx_wrong(int* arr, int b, int e, int key){
int minIdx = b, maxIdx = e, midIdx;
while (minIdx < maxIdx){
midIdx = minIdx + (maxIdx - minIdx) / 2;
if (arr[midIdx] <= key){
minIdx = midIdx;
}
else{
maxIdx = midIdx-1;
}
}
if (arr[maxIdx] == key){
return maxIdx;
}
else if (arr[minIdx] == key){
return midIdx;
}
else{
return -1;
}

}


在写循环(或者递归)程序的时候,特别要注意:初始条件、转换、终止条件!!!!

我也没有考虑到循环的终止条件有可能无法到达。

测试数据与函数调用:

int arr[] = { 1, 3, 3, 4, 4, 7, 8 };
int idx = bisearch_findMaxIdx1(arr,0,6,3);


当minIdx=1,maxIdx=2

=>midIdx=1,arr[midIdx]<=3

=>minIdx=midIdx=1,maxIdx=2

程序进入了死循环

对于循环结束有两种情况:

1.若minIdx为偶数则minIdx==maxIdx

2.minIdx==maxIdx-1

我们可以将maxIdx=midIdx-1,改为maxIdx=midIdx,这样可以避免出现minIdx==maxIdx。

代码:

//给定一个有序数组,求任意一个i使得arr[i]等于v,不存在则返回-1
int bisearch(int* arr,int b,int e,int key){
int l = b, r = e,m;
while (l <= r){
m = l + (r - l) / 2;
if (arr[m] == key){
return m;
}
else if (arr[m]>key){
r = m - 1;
}
else{
l = m + 1;
}
}
return -1;
}

//找出有序数组中,最大的i使得arr[i]=key,不存在返回-1
int bisearch_findMaxIdx(int* arr,int b,int e,int key){
int minIdx = b, maxIdx = e, midIdx;
while (minIdx < maxIdx - 1){
midIdx = minIdx + (maxIdx - minIdx) / 2;
if (arr[midIdx] <= key){
minIdx = midIdx;
}
else{
maxIdx = midIdx;
}
}
if (arr[maxIdx] == key){
return maxIdx;
}
else if (arr[minIdx] == key){
return midIdx;
}
else{
return -1;
}

}

//找出有序数组中,最小的i使得arr[i]=key,不存在则返回-1
int bisearch_findMinIdx(int* arr,int b,int e,int key){
int minIdx = b, maxIdx = e, midIdx;
while (minIdx < maxIdx - 1){
midIdx = minIdx + (maxIdx - minIdx) / 2;
if (arr[midIdx] < key){
minIdx = midIdx;
}
else{
maxIdx = midIdx;
}
}
if (arr[minIdx] == key){
return minIdx;
}
else if (arr[maxIdx] == key){
return maxIdx;
}
else{
return -1;
}
}

//找出有序数组中,最大的i使得arr[i]<key,不存在则返回-1
int bisearch_findMaxIdx1(int* arr,int b,int e,int key){
int minIdx = b, maxIdx = e, midIdx;
while (minIdx < maxIdx - 1){
midIdx = minIdx + (maxIdx - minIdx) / 2;
if (arr[midIdx] < key){
minIdx = midIdx;
}
else{
maxIdx = midIdx;
}
}
if (arr[maxIdx] < key){
return maxIdx;
}
else if (arr[minIdx] < key){
return minIdx;
}
else{
return -1;
}
}

//找出有序数组中,最小的i使得arr[i]>key,不存在则返回-1
int bisearch_findMinIdx1(int* arr, int b, int e, int key){
int minIdx = b, maxIdx = e, midIdx;
while (minIdx < maxIdx - 1){
midIdx = minIdx + (maxIdx - minIdx) / 2;
if (arr[midIdx] <= key){
minIdx = midIdx;
}
else{
maxIdx = midIdx;
}
}
if (arr[minIdx]>key){
return minIdx;
}
else if (arr[maxIdx] > key){
return maxIdx;
}
else{
return -1;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息