1. 程式人生 > >楊氏矩陣查詢數字(遞迴和非遞迴)

楊氏矩陣查詢數字(遞迴和非遞迴)

楊氏矩陣 
有一個二維陣列.
陣列的每行從左到右是遞增的,每列從上到下是遞增的.
在這樣的陣列中查詢一個數字是否存在。
要求:時間複雜度小於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;
}

結果展示: