天天看点

二维数组的查找及向函数传递二维数组问题

问题:在一个二维数组中,每行的元素从左到右是递增的,每列元素从上到下是递增的。写一个函数,查找一给定的元素是否在此数组中

输入:一个二维数组,和一个待查找的数

输出:待查找的数在数组中输出“YES",否则输出”NO"

原始思路:最简单思路就是暴力搜索,遍历一遍数组中的元素时间复杂度为O(n2)。但是这样就没有用问题的已知条件(从左到右、从上到下递增),因此不是个好的解法

改进1:从第一行开始找,找到待查元素大的,如果还没找到,接着从第二行开始找,直到找到或到最后一个元素为止(如图),但是如果带查找的元素在最后,还得遍历到最后,时间复杂度还是O(n2)

改进2:上来在随机在里面挑一个,如果正好逮住,那就结束了;如果比待查找的元素大,那么他的左边和上边;否则在右边和下边。如下图。这样下来可以减少一部分元素的比较。在寻找1时,会话费反而很多时间,并不是个好的解决办法。

二维数组的查找及向函数传递二维数组问题

改进3:看两个比较关键的两个点——左下角和右上角。以右上角为例(如下图)。如果右上角元素等于带查找元素,那就返回真;如果右上角元素大于待查找元素,那就删除右上角元素所在列;否则删除其所在行。依次进行下去。

二维数组的查找及向函数传递二维数组问题

举例说明:

二维数组的查找及向函数传递二维数组问题

参考代码一:

<a></a>

这里注意几个技术细节问题(c语言):

1.二维数组的定义——第二位长度必须指明

      我们知道一位数组定义可以不指名元素总的个数,例如int a[] = {1, 2, 3},编译器会自动赋值长度为3;对于字符char a[] = {'a', 'b', 'c'},自动赋值为4,(因为字符数组末尾有个默认‘\0’字符)

二维数组的本质也是一维数组,其元素是数组。是数组的数组。但是初始化是第二位必须指明int a[][3]是可以的,但是int a[][]绝对不行的。究其这样设计的原因:int a[][3]={1,2,3,4,5}是定义一个每个元素含有3和整形变量的数组的数组。编译器会自动区分为{{1,2,3},{4,5}},但是如果第二维也给省略了,这样编译器也傻眼了,到底给每个数组赋多大值,是{{1,2,3},{4,5,0}},还是{{1,2,3,4},{5,0,0,0}}还是其他......

2.向函数中传递二维数组

 方法一:形参给出第二维大小

方法二:形参指明指向指针的 数组

对于方法二:这里怎么理解int (*a)[3]? 做个类比:应该都知道int  *a指指向整形变量的指针,等价于int  (*a)[1],[1]指明个数。那么int (*a)[3]就是指明了3个指针,a指向第一个。不能去掉(),因为*的优先级小于[],对于a[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}},*a[2]指7。(a[2]指向第2个数组的指针,*取出第一个来)下面程序例证:

执行结果是7

对于方法一有个问题:怎么知道二维数组第一维是多大?对于数组是没有函数得知数组的大小,即传给函数一个数组(数组名)不能得出数组的大小,可以利用sizeof函数得出。

3.sizeof

函数是用来得出一个对象或类型名的长度,单位是字节。返回类型为long unsigned int(c语言输出格式为%lu)

语法:sizeof(object) //对象

         sizeof(type)   //类型

例如:

通过运行结果分析:

下面看一维数组:

运行结果:

 下面看二位数组

执行结果:

二维数组的查找及向函数传递二维数组问题

现在回顾先写到程序,貌似不完全符合题意,题目是传入一个二维数组,但是现在能做的的必须是传入第二维的大小,可不可以直接往函数中直接传二位数组呢?

4.二维数组传给函数当一维数组用——利用下标转换成一维数组的下标

*********************好了,修改下思路三***********************

参考代码二:

本文转自jihite博客园博客,原文链接:http://www.cnblogs.com/kaituorensheng/archive/2013/04/21/3033284.html,如需转载请自行联系原作者

继续阅读