杨氏矩阵:每一行自左向右递增,每一列自上向下递增。
第一种:遍历整个二维数组,这种方法效率最低。
第二种:因为杨氏矩阵每行都是递增的,是有序的,我们可以先判断这个整数是否大于等于每行的第一个元素,小于等于最后一个元素。如果是的话,则对这行使用折半查找法进行查找。这种方法效率次之。
题目:输入一个杨氏矩阵和一个整数,判断这个数是在杨氏矩阵中出现。
第一种:遍历整个二维数组,这种方法效率最低。
第二种:因为杨氏矩阵每行都是递增的,是有序的,我们可以先判断这个整数是否大于等于每行的第一个元素,小于等于最后一个元素。如果是的话,则对这行使用折半查找法进行查找。这种方法效率次之。
第三种:因为每行是递增的,每列也是递增的,我们可以将这个数与最右上角的元素进行比较。如果这个数大于右上角元素,则表明这个数大于这一行元素,因此这个数只可能在这一行的下方出现,所以查找方位缩小到这一行的下方。同样的,如果这个数小于右上角元素,则表明这个数小于这一列元素,因此查找范围可以缩小到这一列的左侧。(也可以与左下角的元素进行比较)这种方式效率最高。
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#define row 4
#define col 3
//第一种
int check_num(int (*p)[col], int num, int line, int rank) //遍历数组
{
int i = 0;
int j = 0;
for (i = 0; i < line; i++)
{
for (j = 0; j < rank; j++)
{
if (p[i][j] == num)
return 1; //存在则返回1
}
}
return 0;
}
//第二种
int check_num(int(*p)[col], int num, int line, int rank)
{
for (int i = 0; i < line; i++)
{
if (num>=p[i][0]&&num <= p[i][rank - 1]) //判断num是否有可能在这行,如果在的话进入if
{
int *left = &p[i][0];
int *right = &p[i][rank - 1];
int *tmp = NULL;
while (left <= right) //折半查找法查找
{
tmp = left + (right - left) / 2;
if (num>=*tmp)
left =tmp + 1;
if (num <= *tmp)
right = tmp - 1;
if (num == *tmp)
return 1; //存在则返回1
}
}
}
return 0;
}
//第三种
int check_num(int(*p)[col], int num, int line, int rank)
{
int i = 0;
int j = rank-1;
while (i < line || j >= 0)
{
if (num < p[i][j]) //如果num小于i行最后一个数,则列自减
j--;
if (num>p[i][j]) //如果num大于i行最后一个数,则行自增
i++;
if (num == p[i][j])
return 1; // 存在则返回1
}
return 0;
}
int main()
{
int n = 0;
int arr[row][col] = { 0 };
for (int i = 0; i < row; i++)
{
for (int j = 0; j <col; j++)
{
scanf("%d", &arr[i][j]);
}
}
scanf("%d", &n);
int ret = check_num(arr, n, row, col);
if (ret==1)
printf("YES\n");
else
printf("NO\n");
system("pause");
return 0;
}