4. 算法笔记-二分查找

1. 在有序数组中查找 number 是否存在。

2. 在有序数组中查找 >=number 的最左位置。

3. 在有序数组中查找 <=number 的最右位置。

4. 峰值问题。

#include <vector>                                                                                                              
#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <algorithm>

class Search{
public:
    int linear_search(const std::vector<int> &vec, int target){
        if(vec.size() == 0)
            return -1; 
        for(int i = 0; i < vec.size(); ++i){
            if(vec[i] == target){
                return i;
            }   
        }   
        return -1; 
    } 

    int binary_search(const std::vector<int> &vec, int target){
        if(vec.size() == 0)
            return -1;
        int left = 0, right = vec.size() - 1, mid = 0;
        while(left <= right){
            mid = (right - left) / 2 + left;
            if(vec[mid] == target){
                return mid;
            }
            else if(vec[mid] > target){
                right = mid - 1;
            }
            else{
                left = mid + 1;
            }
        }
        return -1;
    }

    int binary_greater(const std::vector<int> &vec, int target){
        if(vec.size() == 0)
            return -1;
        int left = 0, right = vec.size() - 1, mid = 0, result = -1;
        while(left <= right){
            mid = (right - left) / 2 + left;
            if(vec[mid] >= target){
                result = mid;
                right = mid - 1;
            }
            else{
                left = mid + 1;
            }
        }
        return result;
    }

    int binary_less(const std::vector<int> &vec, int target){
        if(vec.size() == 0)                                                                                                    
            return -1;
        int left = 0, right = vec.size() - 1, mid = 0, result = -1;
        while(left <= right){
            mid = (right - left) / 2 + left;
            if(vec[mid] > target){
                right = mid - 1;
            }
            else{
                result = mid;
                left = mid + 1;
            }
        }

    int peek_value(const std::vector<int> &vec){
        if(vec.size() == 0)
            return -1;
        if(vec.size() == 1)
            return 0;
        if(vec[0] > vec[1])
            return 0;
        if(vec[vec.size()-1] > vec[vec.size()-2])
            return vec.size()-1;
        int left = 1, right = vec.size()-2, mid = 0;
        while(left <= right){
            mid = (right - left) / 2 + left;
            if(vec[mid - 1] > vec[mid]){
                right = mid - 1;
            }
            else if(vec[mid + 1] > vec[mid]){
                left = mid + 1;
            }
            else{
                return mid;
            }
        }
        return -1;
    }

    void check(int time = 1000, int vec_min = -500, int vec_max = 500, int vec_size = 500){                                    
        std::srand((unsigned)std::time(NULL));
        for(int i  = 0; i < time; ++i){
            std::vector<int> vec;
            for(int i = 0; i < vec_size; ++i){
                int random_number = (std::rand() % (vec_max - vec_min + 1)) + vec_min;
                vec.push_back(random_number);
            }
            std::sort(vec.begin(), vec.end()); 
            vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
            std::vector<int> vec_1 = vec;
            std::vector<int> vec_2 = vec;
            int target = (std::rand() % (vec_max - vec_min + 1)) + vec_min;
            
            int linear_index = this->linear_search(vec_1, target);
            int binary_index = this->binary_search(vec_2, target);
            if(linear_index != binary_index){
                printf("error, linear_index=%d, binary_index=%d ! sample vector is ", linear_index, binary_index);
                printf("{");
                for (auto value : vec){
                    printf(" %d ", value);
                }
                printf("}\n");
                return;
            }
        }
        printf("Successful.\n");
        return;
    }

    void time(int vec_min, int vec_max, int vec_size){
        std::srand((unsigned)std::time(NULL));
        std::vector<int> vec;
        for(int i = 0; i < vec_size; ++i){
            int random_number = (std::rand() % (vec_max - vec_min + 1)) + vec_min;
            vec.push_back(random_number);
        }
        std::sort(vec.begin(), vec.end()); 
        vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
        int target = (std::rand() % (vec_max - vec_min + 1)) + vec_min;
        
        long int linear_start = clock();
        int linear_index = this->linear_search(vec, target);
        long int linear_end = clock();
        
        long int binary_start = std::clock();
        int binary_index = this->binary_search(vec, target);
        long int binary_end = std::clock();
        
        long int linear_run_time = (linear_end - linear_start);
        long int binary_run_time = (binary_end - binary_start);
        printf("linear_run_time: %ld\n", linear_run_time);
        printf("binary_run_time: %ld\n", binary_run_time);
        return;
    }
};

int main(void){
    Search search;
    std::vector<int> vec = {1, 1, 2, 4, 3, 2};
    printf("peek value is: %d.\n", vec[search.peek_value(vec)]);
    return 0;
} 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值