数据结构和算法设计专题之---二分查找(Java版)

1、前提:二分查找的前提是需要查找的数组必须是已排序的,我们这里的实现默认为升序

2、原理:将数组分为三部分,依次是中值(所谓的中值就是数组中间位置的那个值)前,中值,中值后;将要查找的值和数组的中值进行比较,若小于中值则在中值前面找,若大于中值则在中值后面找,等于中值时直接返回。然后依次是一个递归过程,将前半部分或者后半部分继续分解为三部分。可能描述得不是很清楚,若是不理解可以去网上找。从描述上就可以看出这个算法适合用递归来实现,可以用递归的都可以用循环来实现。所以我们的实现分为递归和循环两种,可以根据代码来理解算法

3、实现:代码如下

[java] view plain copy
  1. packageorg.cyxl.algorithm.search;
  2. /**
  3. *二分查找
  4. *@authorcyxl
  5. *
  6. */
  7. publicclassBinarySearch{
  8. privateintrCount=0;
  9. privateintlCount=0;
  10. /**
  11. *获取递归的次数
  12. *@return
  13. */
  14. publicintgetrCount(){
  15. returnrCount;
  16. }
  17. /**
  18. *获取循环的次数
  19. *@return
  20. */
  21. publicintgetlCount(){
  22. returnlCount;
  23. }
  24. /**
  25. *执行递归二分查找,返回第一次出现该值的位置
  26. *@paramsortedData已排序的数组
  27. *@paramstart开始位置
  28. *@paramend结束位置
  29. *@paramfindValue需要找的值
  30. *@return值在数组中的位置,从0开始。找不到返回-1
  31. */
  32. publicintsearchRecursive(int[]sortedData,intstart,intend,intfindValue)
  33. {
  34. rCount++;
  35. if(start<=end)
  36. {
  37. //中间位置
  38. intmiddle=(start+end)>>1;//相当于(start+end)/2
  39. //中值
  40. intmiddleValue=sortedData[middle];
  41. if(findValue==middleValue)
  42. {
  43. //等于中值直接返回
  44. returnmiddle;
  45. }
  46. elseif(findValue<middleValue)
  47. {
  48. //小于中值时在中值前面找
  49. returnsearchRecursive(sortedData,start,middle-1,findValue);
  50. }
  51. else
  52. {
  53. //大于中值在中值后面找
  54. returnsearchRecursive(sortedData,middle+1,end,findValue);
  55. }
  56. }
  57. else
  58. {
  59. //找不到
  60. return-1;
  61. }
  62. }
  63. /**
  64. *循环二分查找,返回第一次出现该值的位置
  65. *@paramsortedData已排序的数组
  66. *@paramfindValue需要找的值
  67. *@return值在数组中的位置,从0开始。找不到返回-1
  68. */
  69. publicintsearchLoop(int[]sortedData,intfindValue)
  70. {
  71. intstart=0;
  72. intend=sortedData.length-1;
  73. while(start<=end)
  74. {
  75. lCount++;
  76. //中间位置
  77. intmiddle=(start+end)>>1;//相当于(start+end)/2
  78. //中值
  79. intmiddleValue=sortedData[middle];
  80. if(findValue==middleValue)
  81. {
  82. //等于中值直接返回
  83. returnmiddle;
  84. }
  85. elseif(findValue<middleValue)
  86. {
  87. //小于中值时在中值前面找
  88. end=middle-1;
  89. }
  90. else
  91. {
  92. //大于中值在中值后面找
  93. start=middle+1;
  94. }
  95. }
  96. //找不到
  97. return-1;
  98. }
  99. }

4、测试代码

[java] view plain copy
  1. packageorg.cyxl.algorithm.search.test;
  2. importorg.cyxl.algorithm.search.BinarySearch;
  3. importorg.junit.Test;
  4. publicclassBinarySearchTest{
  5. @Test
  6. publicvoidtestSearch()
  7. {
  8. BinarySearchbs=newBinarySearch();
  9. int[]sortedData={1,2,3,4,5,6,6,7,8,8,9,10};
  10. intfindValue=9;
  11. intlength=sortedData.length;
  12. intpos=bs.searchRecursive(sortedData,0,length-1,findValue);
  13. System.out.println("Recursice:"+findValue+"foundinpos"+pos+";count:"+bs.getrCount());
  14. intpos2=bs.searchLoop(sortedData,findValue);
  15. System.out.println("Loop:"+findValue+"foundinpos"+pos+";count:"+bs.getlCount());
  16. }
  17. }

5、总结:这种查找方式的使用场合为已排序的数组。可以发现递归和循环的次数是一样的
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值