二分查找以及变异
来源:互联网 发布:java开发合同管理系统 编辑:程序博客网 时间:2024/04/29 10:24
二分查找
1 必须是数组结构,实现查找o(1)。如果是用链表存储的,就无法在其上应用二分查找法了。
2 排序排序
时间复杂度:log(n)
二分查找的基本算法:
递归
array为排序数组
int binarysearch (int array[], int low, int high, int target)
{
if (low > high) return -1;
int mid =low+(high-low)/2;if (array[mid]> target) return binarysearch(array, low, mid -1, target);if (array[mid]< target) return binarysearch(array, mid+1, high, target);//if (midValue == target) return mid;
}
循环:
int binarysearch (int array[], int low, int high, int target)
{
while(low <= high)
{
int mid = (low + high)/2;
if (array[mid] > target)
high = mid - 1;
else if (array[mid] < target)
low = mid + 1;
else //find the target
return mid;
}
//the array does not contain the target
return -1;
}
二分查找法的缺陷
二分查找法的O(log n)让它成为十分高效的算法。不过它的缺陷却也是那么明显的。就在它的限定之上:必须有序,我们很难保证我们的数组都是有序的。当然可以在构建数组的时候进行排序,可是又落到了第二个瓶颈上:它必须是数组。数组读取效率是O(1),可是它的插入和删除某个元素的效率却是O(n)。因而导致构建有序数组变成低效的事情。
解决这些缺陷问题更好的方法应该是使用二叉查找树了,最好自然是自平衡二叉查找树了,自能高效的(O(nlogn))构建有序元素集合,又能如同二分查找法一样快速(O(log n))的搜寻目标数。插入、删除和查找算法的时间复杂度均为O(lgn)。
二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有 下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。 AVL平衡二叉树或为空树,或为如下性质的二叉排序树: (1)左右子树深度之差的绝对值不超过1; (2)左右子树仍然为平衡二叉树. 平衡因子BF=左子树深度-右子树深度.各项操作的时间复杂度:它的插入和删除某个元素的效率O(logN)
2.1.3 Search in Rotated Sorted Array
描述
Suppose a sorted array is rotated at some pivot unknown to you beforehand.
(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).
You are given a target value to search. If found in the array return its index, otherwise return -1.
You may assume no duplicate exists in the array.
2.1.4 Search in Rotated Sorted Array II
描述
Follow up for ”Search in Rotated Sorted Array”: What if duplicates are allowed?
Would this affect the run-time complexity? How and why?
Write a function to determine if a given target is in the array.
//判读一个taregt是否存在有序数组中
考察二分法
**/*分析:
123456789—》6789 1 2345
当
应该是6789 1 2345 后面肯定是升序 然后根据target目标来决定前面还是后面
当
应该是 3456 7 8912 前面肯定是升序 然后根据target目标来决定前面还是后
*/****
function f7(&$arr,$target,$begin,$end){ if(false===is_array($arr)||empty($arr)) return -1; if($end<$begin) return -1; $mid=$begin+intval(($end-$begin)/2); if($arr[$mid]==$target){ return $mid; } /*这是写错的 if($arr[$mid]>$target){ if($arr[$begin]>$target){ return f($arr,$target,$mid+1,$end); }else{ return f($arr,$target,$begin,$mid-1); } }else{ if($arr[$end]>$target){ return f($arr,$target,$mid+1,$end); }else{ return f($arr,$target,$begin,$mid-1); } }*/ if($arr[$begin]>$arr[$mid]){ if($target>$arr[$mid]&&$target<$arr[$end]){ return f7($arr,$target,$mid+1,$end); }else{ return f7($arr,$target,$begin,$mid-1); } }else if($arr[$begin]<$arr[$mid]){ if($target<$arr[$mid]&&$target>$arr[$begin]){ return f7($arr,$target,$begin,$mid-1); }else{ return f7($arr,$target,$mid+1,$end); } }else{//出现相同的时候 return f7($arr,$target,$begin+1,$end); }}
这个写错了*function findSmall($arr,$begin,$end){ if(false===is_array($arr)) return false; if($end<$begin) return ; $n=$end-$begin; if($n==0) return $arr[$begin]; if($n==1) return min($arr[$begin],$arr[$end]); $mid=$begin+intval(($end-$begin)/2); if($arr[$mid]>$arr[$begin]){ if($arr[$mid]>$arr[$end]) return findSmall($arr,$mid+1,$end); else return findSmall($arr,$begin,$mid-1); }else{ return findSmall($arr,$mid,$end);错了 }}
这种题,重点在于根据题意,缩小寻找的范围;
旋转数组的特点:根据判断中间mid和开头对应值的大小来判断前(后)段是升序。
123456789—》6789 1 2345
当
应该是5678 9 1234 前面肯定是升序 ,最小的的肯定在后面。
但是要注意特例:
1234 5 6789 这时候最小的在前面尼。。。
反之 后面肯定是升序,但是最小在前面
例如7891 2 3456 最小在前面
function findSmall($arr,$begin,$end){ if (false === is_array($arr)) return false; if ($end < $begin) return; $n = $end - $begin; if ($n == 0) return $arr[$begin]; if ($n == 1) return min($arr[$begin], $arr[$end]); $mid = $begin + intval(($end - $begin) / 2); /* 该题还要考虑是否存在相同的值 例如 11 1 01 这种情况只能采用顺序查找了。 */ if ($arr[$mid] == $arr[$begin] && $arr[$mid] == $arr[$end]) return shunFind($arr,$begin,$end); if ($arr[$mid] > $arr[$begin]){ if ($arr[$mid] < $arr[$end]){ return findSmall($arr, $begin, $mid); }else return findSmall($arr, $mid, $end); }else return findSmall($arr,$begin,$mid);}
2 .1.5 Median of Two Sorted Arrays
描述
There are two sorted arrays A and B of size m and n respectively. Find the median of the two sorted arrays. the overall run time complexity should be O(log(m + n)).
这个题下标要想清楚~,很容易出错
- 二分查找以及变异
- 顺序查找以及二分查找
- 二分查找以及冒泡排序
- 二分查找以及位图法
- 二分查找以及改进算法
- 二分查找以及二分查找的时间复杂度
- [整理]插入排序以及二分查找排序
- 二分模板以及STL中的查找
- 二分查找代码分析以及应用
- 快速排序以及二分查找的实现
- 二分查找算法详解以及java实现
- 算法 二分查找的变种以及注意事项
- 二分查找之美:二分查找及其变体的正确性以及构造方式
- 二分查找之美:二分查找及其变体的正确性以及构造方式
- 二分查找之美:二分查找及其变体的正确性以及构造方式
- 二分查找之美:二分查找及其变体的正确性以及构造方式
- ACM:二分查找,以及利用二分法来找上下界
- 二分查找的各种情况实现以及一些注意点
- iOS 多个网络请求并发执行的解决方案
- XMPP与Openfire搭建的iOS即时通讯问题
- POI操作Excel常用方法总结
- 003_深入浅出mysql—索引
- Linux常用操作练习
- 二分查找以及变异
- linux下清空大文件的5种方法
- java版+支付宝支付和微信支付(一)
- Percent Bar——百分比工具条控件
- 零基础学习hadoop到上手工作线路指导(初级篇)
- Spring学习之旅(十) Spring MVC实现REST
- Unity游戏开发图片纹理压缩方案
- Touch---load kl文件的过程
- 462. Minimum Moves to Equal Array Elements II 难度:medium