zoukankan      html  css  js  c++  java
  • 查找系列合集-二分查找

    一、二分查找

    【引入】一个综艺节目是给定一件价格为未知整数的商品,默认最高价格为1个亿,

    你每次猜其价格时主持人会告诉你该价格比实际价格高还是低或者相等,现在让你在尽可能少的次数下猜出其价格,请问你的策略是什么?

    【策略】已知上下界1~109,则每次取中间的值,直到猜中为止,时间 复杂度O(logN)相当快

    【伪码描述】

    int a[maxn];//数组a按照从小到大排序
    def find(key){
        int lo = min;//下界
        int hi = max;//上界
        while(lo < hi){
            int mid = lo + (hi - lo) / 2;
            if(a[mid] == key) return mid;
            else if(a[mid] < key){//如果中间值比较小,则在右半边找
                lo = mid + 1;
            }
            else{
                hi =  mid - 1;//如果中间值比较大,则在左半边找
            }
        }
        return -1;//没找到则 返回一个特殊值
    }

    二、基于有序数组的二叉查找树

    package search;
    
    import java.util.Random;
    
    public class BinarySearchST<Key extends Comparable<Key> , Value> {
        private Key[] keys; //
        private Value[] vals; //
        private int N;// 当前使用容量
        
        public BinarySearchST(int capacity) {
            keys = (Key[]) new Comparable[capacity];
            vals = (Value[]) new Object[capacity];
        }
        
        public int size() {
            return N;
        }
        //根据键来查找对应值
        public Value get(Key key) {
            //找出该键在数组中的下标
            int pos = rank(key);
            //如果找到的下标在范围内并且确实是这个键,说明找到了
            if(pos < N && keys[pos].compareTo(key) == 0) {
                return vals[pos];
            }
            else return null;//否则没有找到,返回空
        }
        //二分法查找键的位置
        public int rank(Key key) {
            int lo = 0, hi = N - 1;
            //二分查找
            while(lo <= hi) {
                int mid = lo + (hi - lo) / 2;
                if(keys[mid].compareTo(key) > 0) {
                    hi = mid - 1;
                }
                else if(keys[mid].compareTo(key) < 0 ) {
                    lo = mid + 1;
                }
                else {
                    return mid;
                }
            }
            //如果找不到 之前一步lo必定等于hi, 看这个数字是大于还是小于,不论怎样,lo的位置都代表如果这个数存在
            //它应该处于的位置
            return lo;
        }
        
        public void put(Key key, Value val) {
            int pos = rank(key);//先看这个键有木有
            //如果有只需要修改一下值就行了
            if(pos < N && keys[pos].compareTo(key) == 0) {
                vals[pos] = val;
            }
            //如果没有就新建一个键值对 插入
            //插入的位置正好是pos 那么pos之后的数都要后移一位
            //如果容量已满需要扩容
            for(int i=N-1; i>=pos; i--) {
                keys[i + 1] = keys[i];
                vals[i + 1] = vals[i];
            }
            //空出来的位置插入新键值对
            keys[pos] = key;
            vals[pos] = val;
            N++;
        }
        
        public void delete(Key key) {
            int pos = rank(key);//先看这个键有木有
            //如果有就删除 并且后移一位
            if(pos < N && keys[pos].compareTo(key) == 0) {
                for(int i=pos; i<N-1; i++) {
                    keys[i] = keys[i+1];
                    vals[i] = vals[i+1];
                }
                N--;
            }
            //如果没有就返回
            return;
        }
        
        public void show() {
            for(int i=0; i<N; i++) {
                System.out.println(keys[i].toString() + " : " + vals[i].toString());
            }
        }
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            BinarySearchST<Integer, Integer> bs = new BinarySearchST<Integer , Integer>(20);
            Random r = new Random();
            for(int i=0; i<10; i++) {
                Integer t1 = new Integer(r.nextInt(1000));
                Integer t2 = new Integer(r.nextInt(1000));
                bs.put(t1, t2);
            }
            bs.show();
            System.out.println("*********************");
            bs.put(999, 999);
            bs.put(555, 555);
            bs.show();
            System.out.println("*********************");
            bs.delete(555);
            bs.show();
        }
    
    }
    View Code
  • 相关阅读:
    (HDOJ 2034)人见人爱AB
    (UVa 100) The 3n + 1 problem
    (HDOJ 2099)整除的尾数
    (UESTCOJ 1004)8球胜负(eight)
    asp.net中对数据库表插入null空值的问题
    利用模版生成html页
    如何取得IP/用户名等信息
    SQL SERVER的数据类型
    在IIS与.net框架中配置中把扩展名.aspx改成自定义的扩展名.mspx
    c#中什么情况下用(int)什么情况下用Convert.ToInt32?
  • 原文地址:https://www.cnblogs.com/czsharecode/p/10554345.html
Copyright © 2011-2022 走看看