二分查找极其变形算法


二分查找是典型的分治法的应用,要求待查序列排好序,这里都按照从小到大排列处理,查找时间代价o(log(n)).
思路和中间的数字比较,如果相等则找到,如果<则在左边找,如果>则在右边找。
分治及许多计算机算法的核心就是将问题设法转化为 相同的形式问题而规模减小,即子问题。能够找到规模减小的子问题,意味着问题的解决。
注意分治不一定非要递归,如果每次只走一个分支,那么循环的写法也非常简单,是更好的写法。
 1  def  bsearch(li, val):
 2 
 3      start  =  0
 4 
 5      end  =  len(li)  -   1
 6 
 7       while (start  <=  end):
 8 
 9          middle  =  int((start  +  end) / 2 )
10 
11           if  val  ==  li[middle]:
12 
13               return  middle
14 
15           if  val  <  li[middle]:
16 
17              end  =  middle  -   1
18 
19           else :
20 
21              start  =  middle  +   1
22 
23 
24       return   - 1
二分变形1
在数组中查找val,有可 能数组中有多个相同的val,返回第一个的位置
方法1,二分查找val,找到后向左线性扫描直到遇到更小的。
方法2,找到val以后,对左边的数组继续二分查找直到找到第一个位置
其它方法? TODO参考一下stl的lower bound
下面给出方法2的解法。
 1  """ find the first val like li avove search 3 will return 2 """
 2 
 3  def  bsearch2(li, val):
 4 
 5      start  =  0
 6 
 7      end  =  len(li)  -   1
 8 
 9      find  =   - 1
10 
11       while (start  <=  end):
12 
13          middle  =  int((start  +  end) / 2 )
14 
15           if  val  ==  li[middle]:
16 
17              end  =  middle  -   1
18 
19              find  =  middle
20 
21           if  val  <  li[middle]:
22 
23              end  =  middle  -   1
24 
25           else :
26 
27              start  =  middle  +   1
28 
29       return  find    
二分变形2
将排好序的数组移位,而且不知道具体的移位位置
如1 , 2, 3, 4, 5, 6, 7
移位后可能为
6 , 7, 1, 2, 3, 4, 5     //list1
3, 4, 5, 6, 7, 1, 2     //list2
这样查找过程中,要注意如何能够找到相同形式规模缩小的子问题呢?
仍然二分查找,但是每次下一步查找的区间的确定,就不仅仅由待查找的val和当前数组中间值的关系确定了,要考虑数组的头尾元素值。
例如 list1中查找 7, 那么先和2 比较发现较大, 但是下一步不能去右边区间找,因为7 > list1的首元素了,所以应该在左边区间查找。
注意区分list1,list2的不同 list1的中间值小于list1的首元素,意味着中间值在较小的序列中。
而list2的中间值大于首元素,意味着中间值在较大的序列中。
 1  def  bsearch3(li, val):
 2 
 3      start  =  0
 4 
 5      end  =  len(li)  -   1
 6 
 7       while (start  <=  end):
 8 
 9          mid  =  int((start  +  end) / 2 )
10 
11           # print '*', mid, val, li[mid]
12 
13           if  val  ==  li[mid]:
14 
15               return  mid
16 
17           if  val  ==  li[start]:
18 
19               return  start
20 
21           if  val  ==  li[end]:
22 
23               return  end
24 
25           if  val  <  li[mid]:
26 
27               if  li[mid]  <  li[start]:                  # like  6 7 1 .2. 3 4 5
28 
29                  end  =  mid  -   1                         # here to find 1
30 
31               else :                # li[mid] >= li[start]like  3 4 5 .6. 7 1 2
32 
33                   if  (val  <  li[start]):                # here to find 2
34 
35                      start  =  mid  +   1
36 
37                   else :
38 
39                      end  =  mid  -   1                     # here to find 4
40 
41           else :                # val > li[mid]
42 
43               if  li[mid]  <  li[start]:                  # like  6 7 1 .2. 3 4 5
44 
45                   if  val  <  li[end]:                    # here to find 3 or 4 
46 
47                      start  =  mid  +   1
48 
49                   else :                               
50 
51                      end  =  mid  -   1                     # here to find 7
52 
53               else :                                    # like 3 4 5 .6. 7 1 2
54 
55                  start  =  mid  +   1                       # here to find 7
56 
57       return   - 1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Matlab中,可以使用二分查找法来查找数组中的元素。以下是使用递归实现的二分查找算法的示例代码: ```matlab function BinarySearch_2(array, low, high, value) n = length(array); if low > high fprintf('Sorry, the number does not exist !!! \n\n') else mid = floor((low + high) / 2); if array(mid) == value fprintf('The number is found at position %d. \n\n', mid); elseif array(mid) < value BinarySearch_2(array, mid + 1, high, value); else BinarySearch_2(array, low, mid - 1, value); end end end % 测试数组 BinarySearch_2([1 3 4 6 8 10 13 21 23 46 54 56], 1, 12, 21); ``` 以上代码实现了一个二分查找函数`BinarySearch_2`,接受一个有序数组、数组的下界、上界和要查找的值作为输入。函数会在数组中查找指定的值,并返回它的位置。如果值不存在于数组中,会输出提示信息。 请注意,这只是一个示例代码,你可以根据自己的需求进行修改和扩展。 另外,除了二分查找,Matlab还提供了其他查找方法,比如线性查找、插值查找等。你可以根据具体情况选择合适的查找算法。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [二分查找法及其四种变形(MATLAB)](https://blog.csdn.net/HuiningM/article/details/100173538)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Matlab中顺序查找、二分搜索及一二三次样条的一些总结](https://blog.csdn.net/m0_62961080/article/details/121879268)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值