//有一个二维数组.数组的每行从左到右是递增的,每列从上到下是递增的.在这样的数组中查找一个数字是否存在。
假设一个数组arr[5][5]
以其对角线为参照可以划分为4个区域
1-7 7-13 13-19 19-25
用折半查找的方式来确定所要查询的数据在那一区域内,再用循环语句在锁定的区域内依次查找
代码如下:
//1 2 3 4 5
//6 7 8 9 10
//11 12 13 14 15 rows j=cols j++
//16 17 18 19 20 rowe i=cole i--
//21 22 23 24 25
#include <stdio.h>
#define SZ (sizeof(arr)/sizeof(arr[0]))
int Search(int value, int arr[5][5], int rows, int cols, int rowe, int cole)
{
int i = 0;
for (i = cole; i >= 0; i--)
{
if (value == arr[rowe][i])
{
printf("存在,坐标为: %d %d\n", rowe + 1, i + 1);
}
}
int j = 0;
for (j = cols; j < 5; j++)
{
if (value == arr[rows][j])
{
printf("存在,坐标为: %d %d\n", rows + 1, j + 1);
}
}
return 0;
}
int main()
{
int arr[5][5] = { 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 };
int value = 0;
scanf("%d", &value);
//从对角线开始查找
int rows = 0;
int cols = 0;
int rowe = SZ - 1;
int cole = SZ - 1;
if (value < arr[rows][cols] || value > arr[rowe][cole])
{
printf("不存在\n");
return 0;
}
//折半查找
while (arr[rows][cols] <= arr[rowe][cole])
{
//中间坐标
int rowc = (rows + rowe) / 2;
int colc = (cols + cole) / 2;
if (value == arr[rowc][colc])
{
printf("存在,坐标为: %d %d\n", rowc + 1, colc + 1);
break;
}
if (value < arr[rowc][colc])
{
rowe = rowc;
cole = colc;
if ((rowe - rows) == 1) //锁定查询数在划分的四个区域内
{
Search(value, arr, rows, cols, rowe, cole);
break; //跳出while循环 否则死循环
}
}
if (value > arr[rowc][colc])
{
rows = rowc;
cols = colc;
if ((rowe - rows) == 1)
{
Search(value, arr, rows, cols, rowe, cole);
break;
}
}
}
return 0;
}