`

二维数组中的查找 之 二分法

阅读更多

在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。

请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
例如下面的二维数组就是每行、每列都递增排序。如果在这个数组中查找数字7,则返回true;
如果查找数字5,由于数组不含有该数字,则返回false。
 
我的解题思路是这样的矩阵行列都是从小到大排好序的,要查找的话自然用二分效率比较高,
而且这样的矩阵有个性质,最左上角的元素必定是最小值,最右下角的是最大值,在一个
n*n的矩阵中,对角线的元素也是排好序的,找到对角线上的一个元素,使得这个元素小于
待查找的key,并且下一元素大于待查找的key,那么只要在这个元素的左下角矩阵和右上角
矩阵递归继续对角线查找就可以了,例如上图例子里查找7,只要找到对角线的元素4,然后
递归查找红圈的矩阵就可以了,左上角矩阵最大值4<7,右下角
矩阵最小值10>7,无需查找了,但是此题并没有告诉我们原始矩阵是n*n的,这是比较麻烦的
地方,不过思路是一样的,无非不能用对角线查找这样简单的办法了,假设m*n的矩阵,对角线
查找的办法改进为i = (m1+m2)/2,j = (n1+n2)/2 进行查找就可以了,(m1,n1)为矩阵最左上角
元素下标,(m2,n2)为最右下角元素下标
假设查找17,第一次比较10,然后比较25,然后比较13,返回元素13,这时候再递归查找13
左下角的矩阵和右上角的矩阵就可以了(红色椭圆部分);如果是查找9,第一次比较10,然后比较4,
然后比较6,返回元素6,这时候递归查找6左下角的矩阵和右上角矩阵(绿色椭圆部分)
代码如下:
a是二维数组首地址,(m1, n1)左上角坐标,(m2, n2)右下角坐标,参数n是矩阵一行的元素个数
int binsearch(int value, int *a, int n, int m1, int n1, int m2, int n2)
{
        int begin_m1 = m1, begin_n1 = n1, end_m2 = m2, end_n2 = n2;
        int left_result = 0,  right_result = 0;
        int i = (m1+m2)/2, j = (n1+n2)/2;
        if (a == NULL)
                return 0;
        if (value < *(a+m1*n+n1) || value > *(a+m2*n+n2))
                return 0;
        else if (value == *(a+m1*n+n1) || value == *(a+m2*n+n2))
                return 1;
 
        while ((i!=m1 || j!=n1) && (i!=m2 || j!=n2)){
                 if ( value == *(a+i*n+j) )
                         return 1;
                 else if ( value < *(a+i*n+j) ){
                         m2 = i;
                         n2 = j;
                         i = (i+m1)/2;
                         j = (j+n1)/2;
                  }
                 else{
                         m1 = i;
                         n1 = j;
                         i = (i+m2)/2;
                         j = (j+n2)/2;
                 }
           }
          
           //search left & right
           if ( i<end_m2 )
                   left_result = binsearch(value, a, n, i+1, begin_n1, end_m2, j);
           if ( j<end_n2 )
                   right_result = binsearch(value, a, n, begin_m1, j+1, i, end_n2);
           if (left_result | right_result )
                   return 1;
           else
                   return 0;
}
 
  • 大小: 59.6 KB
  • 大小: 5.8 KB
  • 大小: 12.6 KB
22
4
分享到:
评论
1 楼 lyb520320 2011-12-15  
如何对一个二维数组排序,排序之后的结果可以进行二维数组的二分查找?

相关推荐

    python分治法求二维数组局部峰值方法

    题目的意思大致是在一个n*m的二维数组中,找到一个局部峰值。峰值要求大于相邻的四个元素(数组边界以外视为负无穷),比如最后我们找到峰值A[j][i],则有A[j][i] &gt; A[j+1][i] && A[j][i] &gt; A[j-1][i] && A[j][i] &gt; ...

    二分查找 杨辉三角 数组便利

    实现二分查找 杨辉三角 二维一维数组便利

    计算机二级公共基础知识

    例如,在一维数组[21,46,24,99,57,77,86]中,查找数据元素99,首先从第1个元素21开始进行比较,比较结果与要查找的数据不相等,接着与第2个元素46进行比较,以此类推,当进行到与第4个元素比较时,它们相等,...

    c语言经典源码例子100篇

    实例20 二维数组 实例21 字符数组 // 实例22 数组初始化 // 实例23 数组应用 实例24 函数的值调用 实例25 函数的引用调用 //swap 实例26 数组函数的调用 // 实例27 命令行变元 // 实例28 函数的返回值 实例29 函数的...

    C语言编程精彩百例(附原书源代码)

    实例20 二维数组 实例21 字符数组 实例22 数组初始化 实例23 数组应用 实例24 函数的值调用 实例25 函数的引用调用 实例26 数组函数的调用 实例27 命令行变元 实例28 函数的返回值 实例29 函数的嵌套调用 ...

    leetcode中文版-Jianzhi-offer_python:健智提供python解决方案

    二维数组中的查找 数组 替换空格 字符串 从尾到头打印链表 链表,栈 重建二叉树 二叉树 用两个栈实现队列 栈,队列 斐波那契数列 动态规划 青蛙跳台阶问题 动态规划 旋转数组的最小数字 二分法 矩阵中的路径 dfs ...

    LeetCode判断字符串是否循环-shouzimu:leetcode和算法

    二维数组 Medium √ 7 整数反转 数组 Easy √ 12 整数反转 字符串 Medium √ 13 罗马数字转整数 散列表 Easy √ 15 三数之和 散列表 Medium √ 17 电话号码的字母组合 回溯法 Medium √ 19 删除链表的倒数第N个节点 ...

    二等分方法根查找:使用数组输入的非常简单易用的健壮方法,因此它甚至比fzero更具优势。-matlab开发

    BISECTION是一种处理n维数组的快速,易于使用且健壮的根查找方法。 在bisection方法的其他实现或fzero之类的其他根查找函数中不存在的其他可选输入和输出,用于更多的控制和功能。 在必须循环执行fzero才能解决多种...

    函数中高级

    Excel函数:数组函数、二维引用、多维引用、二分法查找

    天津大学《计算机软件技术基础(2)》在线作业二.docx

    《计算机软件技术基础(2)》在线作业二 一个栈的入栈序列是a,b,c,d,e,则栈不可能的输出序列是( )。 A:edcba B:decba C:dceab D:abcde ... A:分块法 B:顺序法 C:二分法 D:哈希法 参考选项:A 二维数组Amn按行序为主顺

    java内部学习笔记.docx

    3.18二维数组和对象数组 28 3.19其他注意事项 28 Java SE核心I 30 4.1 Object类 30 4.2 String类 31 4.3 StringUtils类 33 4.4 StringBuilder类 33 4.5正则表达式 34 4.6 Date类 35 4.7 Calendar类 35 4.8 ...

    Java实验报告(5).doc

    //二维数组,存取随机数和其固定编号 for(int i=0;i;i++) { anArray[i][0]=(int)(Math.random()*200)+1;//产生100个在1- 200之间的随机数 anArray[i][1]=i+1; } System.out.println("随机产生的数为:"); for(int i=...

    C程序范例宝典(基础代码详解)

    实例031 二维数组行列互换 37 实例032 使用数组统计学生成绩 39 实例033 打印5阶幻方 40 1.6 字符和字符串操作 41 实例034 统计各种字符个数 41 实例035 字符串倒置 43 实例036 字符串替换 44 实例037...

    c程序设计习题参考(谭浩强三版)习题参考解答

    7.8找出一个二维数组中的鞍点,即该位置上的元素在该行上最大,在该列上最小。也可能没有鞍点。 38 7.9有15个数按从小到大的顺序存放在一个数组中。输入一个数,要求用折半查找法找出该数是数组中第几个元素的值。...

    c/c++ 学习总结 初学者必备

    def是一个二级指针,它指向的是一个一维数组的指针,数组的元素都是float. (2)double*(*gh)[10]; gh是一个指针,它指向一个一维数组,数组元素都是double*. (3)double(*f[10])(); f是一个数组,f有10个元素,元素都是...

    数据结构题

    15. 若有18个元素的有序表存放在一维数组A[19]中,第一个元素放A[1]中,现进行二分查找,则查找A[3]的比较序列的下标依次为( ) A. 1,2,3 B. 9,5,2,3 C. 9,5,3 D. 9,4,2,3 16. 对n个记录的文件进行快速...

    C/C++常用算法手册.秦姣华(有详细书签).rar

    6.2.2 二维多项式求值 158 6.2.3 多项式乘法 160 6.2.4 多项式除法 161 6.3 随机数生成算法 164 6.4 复数运算 171 6.4.1 简单的复数运算 172 6.4.2 复数的幂运算 174 6.4.3 复指数运算 176 6.4.4 复对数...

    php网络开发完全手册

    8.1 一维数组与多维数组 119 8.1.1 一维数组简介 119 8.1.2 多维数组简介 119 8.2 常用的数组操作 120 8.2.1 数组的创建与调用 120 8.2.2 数组的更新 121 8.2.3 数组元素的遍历 122 8.3 数组索引与键值的操作技巧 ...

Global site tag (gtag.js) - Google Analytics