第一次盲写二分查找的打脸
来源:互联网 发布:java面向对象实验总结 编辑:程序博客网 时间:2024/06/09 21:45
所谓的盲写,就是在百度百科上简单看了一眼二分查找的原理,在纸上画画伪码,一拍脑袋:哦,想清楚了,小菜一碟。然后下笔如有神,语法都不带检查的大笔一挥,得到第一版代码。
public static int doSearch(int[] arry, int target){ // because arry is ASC if (target < arry[0] || target > arry[arry.length-1]) { return -1; } int low_index = 0; int high_index = arry.length-1; int mid_index; while (low_index < high_index) { mid_index = low_index + (high_index - low_index)/2; int mid_val = arry[mid_index]; if (target > mid_val) { low_index = mid_index; continue; } if (target < mid_val) { high_index = mid_index ; continue; } if (target == mid_val) { return mid_index; } } return -1; }
low_index = mid_index + 1
单元测试一测,一个测试方法一直出不来,代码运算量并不大,果断有死循环。这也给自己提了个醒,测试方法应加上timeout。Debug一下,发现死循环发生在测试下边界值处。原来第一处打脸的地方是在 low_index = mid_index 。
原因分析一下是,当对low_index和high_index之间的区域折半时,得到的一半值mid_index永远会偏向low_index,也就是:恰好有中间整数,得到的就是中间值;如果没有中间整数值,则滑向最接近的低位整数。如果low_index和high_index刚好相差1,mid_index的计算结果一直等于low_index,循环陷在将mid_index的计算结果为low_index然后再赋给low_index中出不来。
因此,low_index = mid_index修改为low_index = mid_index + 1,同时high_index = mid_index - 1。这本身也是折半的原理所在:折半对比,目标大于半数值,从高于折半处截取重新查找(low_index = mid_index + 1);目标小于半数值,从低于折半处截取重新查找(high_index = mid_index - 1);总之不相等则丢弃折半处。
while (low_index < =high_index)
当使用while (low_index < high_index),对于数组长度为5或者6时,索引处1的值查找不出来。原因在于最后一次折半前,高低位重合,跳出循环,而来不及计算mid_index。
最后的写法,通过测试
public static int doSearch(int[] arry, int target){ // because arry is ASC if (target < arry[0] || target > arry[arry.length-1]) { return -1; } int low_index = 0; int high_index = arry.length-1; int mid_index; while (low_index < =high_index) { mid_index = low_index + (high_index - low_index)/2; int mid_val = arry[mid_index]; if (target > mid_val) { low_index = mid_index + 1; continue; } if (target < mid_val) { high_index = mid_index - 1; continue; } if (target == mid_val) { return mid_index; } } return -1;}
- 第一次盲写二分查找的打脸
- 教辅写的二分查找
- python写的二分查找
- 自己写的二分查找法
- DUT 1009 很久以前的第一次写排序+二分
- HDU5676(DFS打表+二分查找)
- 二分查找,要注意的地方--写一个正确的二分查找,并不简单
- 查找顺序数组中元素第一次出现的位置(二分查找)
- 自己写的一个二分查找的c++实现
- 二分查找,这样写行吗
- 用函数写二分查找
- 自写简易vector实现的二分查找
- 写正确函数需要注意的地方:二分查找
- 把二分查找算法写正确需要注意的地方
- 你真的会写二分查找吗
- 你真的会写二分查找吗?
- 你真的会写二分查找吗
- 如何找到二分查找中目标元素第一次出现和最后一次出现的位置
- OpenCV 实现一个自己的Algorithm类
- Oracle中Kill session的研究
- C语言获取系统时间的几种方式
- ajax请求,一次将表单的内容提交的Action
- Edge实现NodeJS与.NET互操作(包括UI界面示例)
- 第一次盲写二分查找的打脸
- 重定向
- 让windows8 变成无线路由器的方法
- 黑马程序员-List-ListIterator-LinkedList-ArrayList
- HDU 2094 -- 产生冠军 (邻接表或直接比较)
- linux selinux对于ftp的控制
- linux系统内核UDP丢包原因分析
- jni问题备忘
- 2.1 创建linkedlist hashset node