对于杨氏矩阵,不知道大家了解多少!想必大家会一开始就认为是一个杨辉三角吧!!其实这二者并没有什么关联!杨氏矩阵:顾名思义,就是一个矩阵:
这儿是百度百科的搜索内容:杨氏矩阵,是对组合表示理论和舒伯特演算很有用的工具。它提供了一种方便的方式来描述对称和一般线性群的群表示,并研究它们的性质。有一个二维数组. 数组的每行从左到右是递增的,每列从上到下是递增的. 在这样的数组中查找一个数字是否存在。 时间复杂度小于O(N); 链接为:杨氏矩阵_百度百科 感兴趣的读者,可以进行欣赏一下!!
言归正传,根据上面的内容:有一个二维数组. 数组的每行从左到右是递增的,每列从上到下是递增的. 在这样的数组中查找一个数字是否存在!!笔者就是在这个基础上进行:编写程序,在这样的杨氏矩阵中查找某个数字是否存在!!!
请看笔者的思考部分:
从矩阵的右上角开始进行查找:原因是:在矩阵的最上角部分:该数字是:一行(i)最小,一列(j)最大的元素!若需要找的元素比它大,则进行下一列i++的查找,一直找到比它小的元素所在的那一列!在进行j--;一直找到该数字!或许等数组的最大值都比该值小,那就是在该数组中,没有该值!!若需要找的元素比它小,则进行j--,一直找到该元素,或者就是没有该数字!
对于上面的理解部分:笔者已经大致讲解清楚,若有什么疑问,请参考代码,进行思考,或者,进行私聊笔者!
请看笔者的代码部分:
#include <stdio.h> void find_num_in_young(int arr[3][3], int k, int r, int c) { int i = 0; int j = c - 1; int flag = 0; while (i <= r - 1 && j >= 0) { if (arr[i][j] < k) { i++; } else if (arr[i][j] > k) { j--; } else { //找到了 flag = 1; printf("找到了,下表为:%d %d\n", i, j); break; } } if (flag == 0) { printf("找不到\n"); } } int main() { int arr[3][3] = { 1,2,3,4,5,6,7,8,9 }; int k = 0; scanf_s("%d", &k); find_num_in_young(arr, k, 3, 3); return 0; }
在这段代码中,比较重要的部分就是在于:函数部分!请大家仔细思考一下!!!
因为是从右上角开始进行查找的!所以有:int i = 0; int j = c - 1; 这样显得很合理!
代码的运行结果为:
对于上述的代码,也可以用指针的方法来进行书写,请看笔者代码!
#include <stdio.h> void find_num_in_young(int arr[3][3], int k, int *px, int *py) { int i = 0; int j = *py - 1; int flag = 0; while (i <= *px - 1 && j >= 0) { if (arr[i][j] < k) { i++; } else if (arr[i][j] > k) { j--; } else { //找到了 flag = 1; *px = i; *py = j; break; } } if (flag == 0) { *px = -1; *py = -1;//返回一个无关紧要的值 ,加以区分!! } } int main() { int arr[3][3] = { 1,2,3,4,5,6,7,8,9 }; int k = 0; scanf_s("%d", &k); int x = 3; int y = 3; find_num_in_young(arr, k, &x, &y); if (x == -1 && y == -1) { printf("找不到\n"); } else printf("找到了,下表为:%d %d\n", x, y); return 0; }
上面的代码,大家仔细分析,也就能区分出来:笔者为什么会这样去写了!
代码的运行结果为:
主要原因还是在于:在函数部分,返回值只能有一个,但是对于有两个返回值类型的数据,可以用void类型来进行传址调用!所以显得很简单!对于其他的用两个for循环,依次进行遍历数组的简单做法,笔者在此就不做过多的讲述!或者也可以在函数里面定义一个数组,里面存放找到后该元素的两个下标,在返回数组名,也是可以的!在此,笔者也不进行讲述,有想法的老铁!请自我思考!