含有重复元素的二分查找算法

1 实现

rust已经有binary_search了,但不能很好的处理有重复元素的查找。
下面这个是我按照网上查找到的原理自己实现的,这个处理重复元素比较好,如果key有重复,那么查找到的总是最小的那个index

fn main() {
    let s = [0, 0,0,0,0,1,1,1, 1, 1, 1, 2,2,3, 3, 5, 8, 13, 21, 34, 55];

    let seek = 1;
    let mut left = 0;
    let mut right = s.len()-1;
    let mut mid;
    while left < right {
        mid = (left + right) >> 1;
        assert!(mid < right);
        if s[mid] < seek {
            left = mid + 1;
        }else{
            right = mid;
        }
    }

    //自己实现的二分查找的结果
    println!("search value:{}\nleft:{},right:{}\nfind:\n idx:{},value:{}",seek,left,right,left,s[left]);

    //调用rust实现的二分查找
    println!("{:?}",s.binary_search(&1));
}

Play地址:https://is.gd/1PJo67
运行结果:

search value:1
left:5,right:5
find:
  idx:5,value:1
Ok(10)

自己实现的二分查找找到了第一个”1”的位置了,而rust自带的binary_search找到的并不一定是第一个”1”

2 简单的性能测试

做了个简单的bench,可以看到我的这个实现与库实现的差别很小,估计库也没有做优化了,先贴结果:

test bench_binary_search … bench: 42 ns/iter (+/- 9)
test bench_binary_search_lib … bench: 41 ns/iter (+/- 11)

这几个全局变量控制测试长度的

static test_len:usize = 1000;
static test_linear_key:u32 = 500;
static test_binary_key:u32 = 200;

注:因为rust自带的binary_search不能很好的处理key重复的情况,所以就用不重复的数组进行测试

2.1 自己实现的算法:

#[bench]
fn bench_binary_search(b: &mut Bencher) {
    let mut v:Vec<u32> = Vec::with_capacity(test_len);
    for i in (0..test_len) {
        v.push(i as u32);
    }

    b.iter(|| {
        let mut left = 0;
        let mut right = test_len-1;
        let mut mid = 0;
        while left < right {
            mid = (left + right) >> 1;
            assert!(mid < right);
            if v[mid] < test_binary_key {
                left = mid + 1;
            }else{
                right = mid;
            }
        }
        assert!((left == right) && (v[left] == test_binary_key));
    });
}

2.2 使用库自带的二分查找:

#[bench]
fn bench_binary_search_lib(b: &mut Bencher) {
    let mut v:Vec<u32> = Vec::with_capacity(test_len);
    for i in (0..test_len) {
        v.push(i as u32);
    }

    b.iter(|| {
        if let Ok(idx) = v.binary_search(&test_binary_key) {
            assert!(v[idx] == test_binary_key);
        }else{
            assert!(false);
        }
    });
}
    原文作者:查找算法
    原文地址: https://blog.csdn.net/varding/article/details/48542807
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞