初识算法—二分法初探

一、什么是算法?

算法是一组完成任务的指令,任何代码片段都可以称为是算法。

本人理解算法区别于程序的概念,是为了更快执行任务的一组指令。是类似与书的目录,数据库的主键的东西,有优化的意思,不然不好意思叫那个名字。

 

二、二分法

二分查找是一种算法,查找的资源必须是一个有序的元素列表(如果无序,二分法无实现意义,无法做到每比较一次缩小一次查找范围,因为本来就没有规则可言)。如果查找的元素包含在列表中,二分查找返回其位置,否则返回null。

下面举个例子

假设要在1~100之间的查找数字49。按照普通的方法,一个一个比较则要比较正序49次,倒序51次。

那么按照二分法

设二分法值为 n

查找存在一个范围,那么设 起始点为 int min=0,终止点 int max=100-1(数组下标)

n = 49 > (min+max)/2?(min=(n+1)+max)/2:(max=(n-1)+min)/2 

n==49则返回

第一次二分100/2等于50,判断49是否大于等于50,否

第二次二分50-50/2=25,继续判断49是否大于等于25,大于

第三次二分25/2+25=37,继续判断49是否大于等于37,大于

第四次二分12.5/2+37=43,继续判断49是否大于等于43,大于

第五次二分6.25/2+43=46,继续判断49是否大于等于46,大于

第六次二分3.125/2+46=48,继续判断49是否大于等于48,大于

第七次二分1.625/2+48=49,继续判断49是否大于等于49,等于

总结为 二分法 最大的比较次数为 log 2(n),n为查找范围最大值

 

 三、二分法具体java代码测试

package com.calcMethod;

import java.util.Arrays;
import java.util.Scanner;

/**
 * @Auther: lanhaifeng
 * @Date: 2019/7/3 0003 08:57
 * @Description: 二分法
 */
public class Dichotomy {

    public static int binarySearch(int[] a , int key){
        int count=0; //二分次数
        int min  = 0; //最小下标
        int max = a.length-1 ;//最大下标
        while(min <= max){
            int mid = (min + max) / 2; //中间索引
            count++;
            System.out.println("最小下标:"+min + ",最大下标:" + max+",二分次数:"+count);  //循环的次数
            int midVal = a[mid];  //中间元素 猜测的值
            System.out.println("二分索引("+min+"+"+max+")/2="+mid+",array["+mid+"]="+midVal);
            if(midVal > key){ //大了
                max  = mid -1;
            }else if(midVal < key){ //小了
                min = mid +1;
            }else{
                return mid;  //等于
            }
        }
        return -1;
    }


    public static void main(String[] args) {
        Scanner input=new Scanner(System.in);
        System.out.println("二分法查找测试,本方法只限数字,范围1~n");
        System.out.println("请输入二分法查找最大值,如输入100,则查找范围为1-100:");
        int maxNum=input.nextInt();
        int[] array=new int[maxNum];
        //创建数组
        for (int i = 0; i < maxNum; i++) {
            array[i]=i+1;
            System.out.println(array[i]);
        }
        System.out.println("请输入1~"+maxNum+"区间要查找的数字(整数):");
        int lookUpNum=input.nextInt();
        int index = binarySearch(array, lookUpNum);
        if(index!=-1){
            System.out.println("查询"+lookUpNum+"在数组中的下标为:"+index) ;
        }
    }
}

打印日志,可以看到每二分一次,都缩小一次最大或最小范围值

 

posted @ 2019-07-03 14:08  别动我的猫  阅读(883)  评论(0编辑  收藏  举报