杨氏矩阵查找数字(递归和非递归)

杨氏矩阵 
有一个二维数组.
数组的每行从左到右是递增的,每列从上到下是递增的.
在这样的数组中查找一个数字是否存在。
要求:时间复杂度小于O(N); 

例:  1 2 3
         4 5 6
         7 8 9

这里时间复杂度O(N) = row + col;            //行数+列数

要使时间复杂度小于O(N),则必须从右上角开始走或者从左下角开始,如图所示,最长也是5,小于行数+列数

这里就这两种策略来写,分别采用递归和非递归的方式:

我在代码中写了4个函数皆可实现要求:

    1. Seek1();       //非递归    右上角开始找

    2. Seek2();       //非递归    左下角开始找

    3. Sreach1();    //递归     右上角开始找

    4. Sreach2();    //递归     左下角开始找

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>

#define ROW 3
#define COL 3

//1.从右上角开始找:
//             如果目标值大于当前值,向下找;小于,向左找
void Seek1(int arr[ROW][COL], int key, int *px, int *py)
{
	int i = 0;
	int j = COL - 1;
	while ((i < ROW) && (j >= 0))
	{	
		if (arr[i][j] == key)
		{
			*px = i;
			*py = j;
			return;
		}
		else if(arr[i][j] < key)
		{
		    i++;
		}
		else
		{
			j--;
		}
	}
	*px = -1;
}

//2.从左下角开始找:
             //如果目标值大于当前值,向右找;小于,向上找
void Seek2(int arr[ROW][COL], int key, int *px, int *py)
{
	int i = ROW - 1;
	int j = 0;
	while ((i >= 0) && (j < COL))
	{
		if (arr[i][j] == key)
		{
			*px = i;
			*py = j;
			return;
		}
		else if (arr[i][j] < key)
		{
			j++;
		}
		else
		{
			i--;
		}
	}
	*px = -1;
}

//递归  右上角开始找
int Sreach1(int arr[ROW][COL], int key, int *px, int *py, int i, int j)
{
		// 出口
	if ((i >= ROW) || (j < 0))
	{
		// 没有找到,px赋值为-1,返回0
		*px = -1;
		return 0;
	}
	if (arr[i][j] == key)
	{
		*px = i;
		*py = j;
		// 找到了,px,py赋值坐标,返回1
		return 1;
	}
	else if (arr[i][j] > key)
	{
			// 如果当前值大于key,向左走,找更小的值
			return Sreach1(arr, key, px, py, i, j - 1);
	}
	else
	{
			// 如果当前值小于key,向下走,找更大的值
			return Sreach1(arr, key, px, py, i + 1, j);
	}
}


//递归  左下角开始找
int Sreach2(int arr[ROW][COL], int key, int *px, int *py, int i, int j)
{
	// 出口
	if ((i < 0) || (j >= COL))
	{
		// 没有找到,px赋值为-1,返回0
		*px = -1;
		return 0;
	}
	if (arr[i][j] == key)
	{
		*px = i;
		*py = j;
		// 找到了,px,py赋值坐标,返回1
		return 1;
	}
	else if (arr[i][j] > key)
	{
		// 如果当前值大于key,向上走,找更小的值
		return Sreach2(arr, key, px, py, i - 1, j);
	}
	else
	{
		// 如果当前值小于key,向右走,找更大的值
		return Sreach2(arr, key, px, py, i, j + 1);
	}
}

Is_find(int px, int py)
{
	if (px != -1)
	{
		printf("找到了!数组下标为:%d,%d\n", px, py);
	}
	else
	{
		printf("没找到!\n");
	}
}

int main()
{
	int arr[ROW][COL] = { {1,2,3},{4,5,6},{7,8,9} };
	int px = 0;
	int py = 0;
	int i = 0;
	int j = 0;
	int key = 0;
	scanf("%d", &key);

        Seek1(arr, key, &px, &py);//非递归 右上角开始找
	Is_find(px, py);

	Seek2(arr, key, &px, &py);//非递归 左下角开始找
	Is_find(px, py);

	Sreach1(arr, key, &px, &py, 0, COL - 1);//递归  右上角开始找
	Is_find(px, py);

	Sreach2(arr, key, &px, &py, ROW - 1, 0);//递归  左下角开始找
	Is_find(px, py);

	system("pause");
	return 0;
}

结果展示:

 

猜你喜欢

转载自blog.csdn.net/Watery________1314/article/details/83663078