• Java基本查找、二分查找、插值查找、分块查找


    目录

    1、基本查找方法

    2、二分查找

    3、插值查找

    4、分块查找


    1、基本查找方法

    基本查找核心:从0索引开始挨个往后查找

    需求:定义一个方法,利用基本查找,查询某个元素是否存在

    代码如下

    1. /**
    2. * @authorDesc
    3. * @author
    4. * @date
    5. * @version 1.0.0
    6. * @description 基本查找
    7. * 核心:从0索引开始挨个往后查找
    8. * 需求:定义一个方法,利用基本查找,查询某个元素是否存在
    9. */
    10. public class BasicSearch {
    11. public static void main(String[] args) {
    12. int[] numArray = {1,2,3,4,5,6,4,4};
    13. int number = 4;
    14. System.out.println(search(numArray,number));
    15. }
    16. /**
    17. * @description
    18. * @author
    19. * @date
    20. * @param numArray 数组
    21. * @param number 要查找的数字
    22. * @retur {@link int} 返回元素下表
    23. */
    24. public static int search(int[]numArray,int number){
    25. for (int i = 0; i < numArray.length; i++) {
    26. if (numArray[i] == number){
    27. return i;
    28. }
    29. }
    30. return -1;
    31. }

    需求:定义一个方法,利用基本查找,查询某个元素是否存在,如果有重复的元素,把所有元素找出

    1. /**
    2. * @description
    3. * @author
    4. * @date
    5. * @param numArray 数组
    6. * @param number 要查找的数字
    7. * @return {@link List} 返回元素下标集合
    8. */
    9. public static List search(int[]numArray,int number){
    10. List<Integer> listnum = new ArrayList<>();
    11. for (int i = 0; i < numArray.length; i++) {
    12. if (numArray[i] == number){
    13. listnum.add(i);
    14. }
    15. }
    16. return listnum;
    17. }
    18. }

    2、二分查找

    前提条件:数组中的数据必须是有序的

    核心:每次排除一半的查找范围

    代码如下

    1. /**
    2. * @authorDesc
    3. * @author
    4. * @date
    5. * @version 1.0.0
    6. * @description 二分查找
    7. * 核心:每次排除一半的查找范围
    8. * 需求:定义一个方法利用二分查找,查询某个元素是否在数组中
    9. */
    10. public class BinarySearch {
    11. public static void main(String[] args) {
    12. int [] numArray = {1,2,3,4,5,6};
    13. int number = 3;
    14. System.out.println(search(numArray,number));
    15. }
    16. /**
    17. * @description
    18. * @author
    19. * @date
    20. * @param numArray 数组
    21. * @param number 查找的数字
    22. * @return {@link int} 返回在数组中的下标
    23. */
    24. public static int search(int [] numArray, int number){
    25. //定义两个变量记录要查找的范围 min数组第一个元素的索引,max 数组最后一个元素的索引
    26. int min = 0;
    27. int max = numArray.length - 1;
    28. //利用循环查找
    29. while (true){
    30. if (min > max){
    31. return -1;
    32. }
    33. //找到min和max的中间值
    34. int mid = (min + max) / 2;
    35. // 用mid 指向的元素和要查找的元素进行比较
    36. if (numArray[mid] > number){
    37. //要查找的数字在mid的左边
    38. //min不变, max = mid - 1
    39. max = mid - 1;
    40. }else if (numArray[mid] < number){
    41. //要查找的数字在mid的右边
    42. //max不变,min = mid + 1
    43. min = mid + 1;
    44. }else {
    45. //查找的元素和mid指向得到元素一样
    46. return mid;
    47. }
    48. }
    49. }
    50. }

    二分查找的优势:提高查找效率

    二份查找条件:1、数据必须是有序的

    2、如果数据是乱的,先排序再用二分法查找得到的索引没有意义,只能确定当前数字在数组中是否存在,因为排序后的数字位置发生了变化

    二分查找的过程:min和max表示当前要查找的范围

    mid是在min和max中间的数字

    如果要查找的元素在mid左边,缩小范围时,min不变,max等于mid减1

    如果要查找的元素在mid右边,缩小范围时,max不变,min等于mid减1

    3、插值查找

    1. //插值查找
    2. int mid = min + (number - numArray[min]) /(numArray[max] - numArray[min]) * (max - min);

    和二分查找相似,将中间值mid改为:

    int mid = min + (number - numArray[min]) /(numArray[max] - numArray[min]) * (max - min);

    4、分块查找

    原则:1、前一块中的最大数据,小于后一块中的所有数据(块内无序,块间有序)

    2、块数数量一般等于元素个数的开根号,比如16个数字一般分为4块

    核心:先确定要查找的元素在哪一块,然后在挨个查找

    代码如下

    1. /**
    2. * @authorDesc
    3. * @author
    4. * @date
    5. * @version 1.0.0
    6. * @description 使用分块查找数组中的元素
    7. */
    8. public class BlockSearch {
    9. public static void main(String[] args) {
    10. int[] numArray = {2,3,1,4,
    11. 8,6,7,5,
    12. 9,11,10,12,
    13. 15,14,13,16};
    14. //创建三个快的对象
    15. Block b1 = new Block(4,0,3);
    16. Block b2 = new Block(8,4,7);
    17. Block b3 = new Block(12,8,11);
    18. Block b4 = new Block(16,12,15);
    19. //定义数组用来管理三个快的对象
    20. Block [] blockArray = {b1,b2,b3,b4};
    21. //定义一个变量用来记录要找的元素
    22. int number = 5;
    23. //调用方法,传递索引表,数组,要查找的元素
    24. int index = getIndex(blockArray,numArray,number);
    25. System.out.println(index);
    26. }
    27. /**
    28. * @description 定义一个方法,用来确定number在哪一块中
    29. * @author
    30. * @date
    31. * @param blockArray 数组
    32. * @param number 要查找的元素
    33. * @return {@link int} 返回下标
    34. */
    35. public static int findBlock(Block[] blockArray,int number){
    36. //Block b1 = new Block(4,0,3);-----0
    37. //Block b2 = new Block(8,4,7);-----1
    38. //Block b3 = new Block(12,8,11);----2
    39. //Block b4 = new Block(16,12,15);----3
    40. //0索引开始遍历,如果bunber小于max,那么number就在这一块中
    41. for (int i = 0; i < blockArray.length; i++) {
    42. if (number <= blockArray[i].getMax()){
    43. return i;
    44. }
    45. }
    46. return -1;
    47. }
    48. /**
    49. * @description
    50. * @author
    51. * @date
    52. * @param blocks 传递索引表,,
    53. * @param numArray 数组
    54. * @param number 要查找的元素
    55. * @return {@link int} 返回下标
    56. */
    57. public static int getIndex(Block [] blocks,int [] numArray,int number){
    58. //确定number实在那一块中
    59. int indexBlock = findBlock(blocks,number);
    60. if (indexBlock == -1){
    61. return -1;
    62. }
    63. //获取这一块的起始索引和结束索引
    64. //Block b1 = new Block(4,0,3);-----0
    65. //Block b2 = new Block(8,4,7);-----1
    66. //Block b3 = new Block(12,8,11);----2
    67. //Block b4 = new Block(16,12,15);----3
    68. int startIndex = blocks[indexBlock].getStartIndex();
    69. int endIndex = blocks[indexBlock].getEndIndex();
    70. //循环遍历
    71. for (int i = startIndex; i < endIndex; i++) {
    72. if (numArray [i] == number){
    73. return i;
    74. }
    75. }
    76. return -1;
    77. }
    78. static class Block{
    79. private int max;//最大值
    80. private int startIndex;//起始索引
    81. private int endIndex;//结束索引
    82. public Block() {
    83. }
    84. public Block(int max, int startIndex, int endIndex) {
    85. this.max = max;
    86. this.startIndex = startIndex;
    87. this.endIndex = endIndex;
    88. }
    89. /**
    90. * 获取
    91. * @return max
    92. */
    93. public int getMax() {
    94. return max;
    95. }
    96. /**
    97. * 设置
    98. * @param max
    99. */
    100. public void setMax(int max) {
    101. this.max = max;
    102. }
    103. /**
    104. * 获取
    105. * @return startIndex
    106. */
    107. public int getStartIndex() {
    108. return startIndex;
    109. }
    110. /**
    111. * 设置
    112. * @param startIndex
    113. */
    114. public void setStartIndex(int startIndex) {
    115. this.startIndex = startIndex;
    116. }
    117. /**
    118. * 获取
    119. * @return endIndex
    120. */
    121. public int getEndIndex() {
    122. return endIndex;
    123. }
    124. /**
    125. * 设置
    126. * @param endIndex
    127. */
    128. public void setEndIndex(int endIndex) {
    129. this.endIndex = endIndex;
    130. }
    131. }
    132. }

  • 相关阅读:
    计算机论文从撰写到选刊,letpub看几区,论文开源和不开源,论文检索网站有哪些
    电脑静态ip地址在哪里找
    将树的某个叶子节点向上提一个level
    第13章: 常用类
    C++图解模板
    16字节协议的串口通信
    Express-01
    【知识点】怎么确定时间复杂度与空间复杂度
    03 转换css元素的类别
    JAVAEE初阶相关内容第十五弹--网络編程
  • 原文地址:https://blog.csdn.net/qi341500/article/details/126688184