0%

01-复杂度3 二分查找

本题要求实现二分查找算法。

函数接口定义:

1
Position BinarySearch( List L, ElementType X );

其中List结构定义如下:

1
2
3
4
5
6
typedef int Position;
typedef struct LNode *List;
struct LNode {
ElementType Data[MAXSIZE];
Position Last; /* 保存线性表中最后一个元素的位置 */
};

L是用户传入的一个线性表,其中ElementType元素可以通过>、==、<进行比较,并且题目保证传入的数据是递增有序的。函数BinarySearch要查找XData中的位置,即数组下标(注意:元素从下标1开始存储)。找到则返回下标,否则返回一个特殊的失败标记NotFound

裁判测试程序样例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <stdio.h>
#include <stdlib.h>

#define MAXSIZE 10
#define NotFound 0
typedef int ElementType;

typedef int Position;
typedef struct LNode *List;
struct LNode {
ElementType Data[MAXSIZE];
Position Last; /* 保存线性表中最后一个元素的位置 */
};

List ReadInput(); /* 裁判实现,细节不表。元素从下标1开始存储 */
Position BinarySearch( List L, ElementType X );

int main()
{
List L;
ElementType X;
Position P;

L = ReadInput();
scanf("%d", &X);
P = BinarySearch( L, X );
printf("%d\n", P);

return 0;
}

/* 你的代码将被嵌在这里 */

输入样例1:

1
2
3
5
12 31 55 89 101
31

输出样例1:

1
2

输入样例2:

1
2
3
3
26 78 233
31

输出样例2:

1
0

编码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <stdio.h>
#define MAXSIZE 10
#define NotFound 0

typedef int ElementType;
typedef int Position;
typedef struct LNode *List;
struct LNode {
ElementType Data[MAXSIZE];
Position Last;
};

List ReadInput();//其它实现
Position BinarySearch(List L, ElementType X);

int main() {
List L;
ElementType X;
Position P;
L = ReadInput();

ElementType arr[] = {12, 34, 56, 78};

scanf("%d", &X);
P = BinarySearch(L, X);

printf("position:%d", P);
return 0;
}

/**
* 非递归分治法
* 也可递归分治法
* @param L
* @param X
* @return
*/
Position BinarySearch(List L, ElementType X) {
Position position = NotFound;
if (L == NULL) {
return position;
}
int left = 1, right = L->Last, mid;
// 1. 遍历链表
while (left <= right) {
mid = (left + right) / 2;
// 2.如果元素X等于数组中间值,说明找到,返回
if (X == L->Data[mid]) {
position = mid;
break;
// 3.如果X比中间值大,left取mid+1向右查找
} else if (X > L->Data[mid]) {
left = mid + 1;
} else {
// 4.如果X比中间值小,right取mid-1向左查找
right = mid - 1;
}
}
return position;
}

小结:

  1. 遍历链表
  2. 如果元素X等于数组中间值,说明找到,返回
  3. 如果X比中间值大,left取mid+1向右查找
  4. 如果X比中间值小,right取mid-1向左查找