Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Java基础数据结构 1.4 改进的二分查找法(平衡) #14

Open
zemise opened this issue Jun 12, 2023 · 0 comments
Open

Java基础数据结构 1.4 改进的二分查找法(平衡) #14

zemise opened this issue Jun 12, 2023 · 0 comments
Labels

Comments

@zemise
Copy link
Owner

zemise commented Jun 12, 2023

1.4 改进的二分查找法(平衡)

分析if的判断次数

未改进的算法:如果要查找的元素在左边就要判断L次,若在右边就要判断2*L次。

public class BinarySearch {

    /**
     * <p>
     * 未改进的二分查找基础版
     * <p>
     *
     * @param a      待查找的升序数组
     * @param target 待查询的目标值
     * @return int 找到返回索引,找不到返回 -1
     * @author Zemise
     * @since 2023/06/12
     */
    public static int binarySearchBasic(int[] a, int target) {
        int i = 0;
        int j = a.length - 1;           // 设置指针和初始值
      
       // L次 元素在最左边L次		元素在最右边 if的比较次数则为 2*L 次
        while (i <= j) {                // i~j 范围内还有东西
          
            int m = (i + j) >>> 1;

            if (target < a[m]) {        // 目标在左边
                j = m - 1;
            } else if (a[m] < target) { // 目标在右边
                i = m + 1;
            } else {                    // 找到了
                return m;
            }
        }

        return -1;
    }

改进版

public static int binarySearch(int[] a, int target){
    int i = 0;           //1 在左闭右开的区间,i指向的可能是目标 j只作为边界
    int j = a.length;
    while(1 < j - i){    //2 不在循环内找出,等范围内只剩i时,退出循环,在循环外比较a[i]与target
        int m = (i+j) >>> 1; 
        if(target < a[m]){
            j = m;
        }
        else{
            i = m;
        }
    }
  
    if(a[i] == target){    //3 在循环外比较平均次数减少了
        return i;          //4 时间复杂度Ɵ(log(n))
    }
    else{
        return -1;
    }
}

改进之后:

​ 优点:循环内的平均比较次数减少了

​ 缺点:为改进之前最好的情况时间复杂度为$O(1)$

​ 改动之后最好和最坏的情况都是$O(log(n))$

@Test
@DisplayName("binarySearchBasic java自带版")
public void test8() {
  int[] a = {2, 5, 8};
  int target = 4;

  /*
            [2, 5, 8]       a
            [2, 0, 0, 0]    b
            [2, 4, 0, 0]    b
            [2, 4, 5, 8]    b
         */

  // 注意,下方说的插入点,其实就是在数组中没有找到目标数据时,会返回目标数据该插入的索引位置
  int i = Arrays.binarySearch(a, target);
  // -2 = -插入点 - 1
  // -2 + 1 = -插入点

  if (i < 0) {
    int insertIndex = Math.abs(i + 1); // 获得插入点索引

    int[] b = new int[a.length + 1];
    System.arraycopy(a, 0, b, 0, insertIndex);
    b[insertIndex] = target;

    System.arraycopy(a, insertIndex, b, insertIndex + 1, a.length - insertIndex);
    System.out.println(Arrays.toString(b));
  }
}
@zemise zemise added the Java label Jun 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant