数据结构与算法基础-02-二分查找-实践


算法中查找算法排序算法可谓是最重要的两种算法,是其他高级算法的基础。在此系列文章中,将逐一学习和总结这两种基础算法中常见的算法实现。首先,第一种算法——二分(折半)查找的学习和练习。


1、概念

二分查找,是逐次将查找范围折半缩小搜寻的范围直到找到那个需要的结果。它是一种效率较高的查找算法,但是要使用它来完成查找任务,有一个前提,那就是所要搜寻的范围的数据结构是采用线性存储结构的线性表,且它已经将数据排好序,常见的有数组,下文以数组为例进行说明。

2、算法思想

每次取数组中间位置的值与需要查找的值比较,如果中间位置的值比需要查找的值大,则在数组前半部分循环这个查找的过程;如果中间位置的值比需要查找的值小,则在数组后半部分循环这个查找的过程。直到查找到了为止,否则数组中没有需要查找的值。

【注意】因为需要确定每次查找的区间范围,所以我们用pow表示区间的上界序号,low表示区间的下界序号,middle表示中间位置序号。

代码:


#include <iostream>
#define NotFound -1

using namespace std;

/* To get the length of the objective array[] */
int get_array_len(int array[] ){
    int len =0;
    len =(sizeof(array) / sizeof(array[0]));
    if (len <= 0 ){
        std::cout << "error"<< endl;
        return -1;
    }
    return len;
}


int binarySearch( int a[],int value)
{
    int low = 0;
    int middle = 0;               //定义区间下界并初始化为0,声明中间位置变量middle
    int len = get_array_len(a);          //计算数组长度,返回长度len
    if (len == -1){
        return -1;
    }
    int high = len;               //上界high,初值为len
    if(a == NULL){
        return NotFound;
    }                           //如果数组为空,结束操作,返回-1

    while(low <= high)
    {
        if (value > a[high]){
            return NotFound;
        }
        middle = (low+high) /2;     //为middle开始赋予初值
        if(a[middle] == value)      //先判断middle所在处的值是不是需要查找的值
            return middle;         //返回查找到的目标值序号
        else if(a[middle] > value)    //若middle处的值大于需要查找的值,则将搜寻范围缩小到前半部分
            high = middle - 1;
        else
            low = middle + 1;      //若middle处的值小于需要查找的值,则将搜寻范围缩小到后半部分
    }
    return NotFound;               //若循坏结束,即high<low,说明需要查找的值不存在,则返回x查找失败标志-1
}

/* check the input number */

int input_check (){
    int num;
    cout<<"请输入A/B中元素个数:"<<endl;
    cin>>num;
    bool flag = false;       //判断标志位,如果r输入数大于100000,标志位置置false
    while (!flag){                     //依题意,元素个数应小于1000000
        if(num >1000000){
            cout<<"元素个数应小于1000000,请重新输入:"<<endl;
            cin>>num;
            flag = false;         //大于100000false
        }
        else{
            flag = true;
        }
    }
    return num;
}

int main()
{

    int n = 0,m = 0;   //从键盘录入A,B两个集合中的元素个数
    n = input_check();    //从键盘读入n并判断其是否符合要求
    m = input_check();

    int *a = new int[n];  //创建动态数组-A集合
    int *b = new int[m]; //创建动态数组-B集合
    int *list = new int[m<=n? m: n]; //定义一个List来存放A,B中相同的元素


    for(int i = 0;i<n;i++){     //给A中每个元素赋值
        cout<<"A中元素值:"<<endl;
        cin>>a[i];
    }
    int* p = NULL;
    p = list;

    for(int i=0;i<m;i++){
            cout<<"B中元素值:"<<endl;
            cin>>b[i];
            int result = binarySearch(a, b[i]); //对输入的每个B数组元素,在A中进行二分查找,并将查找结果返回至result
            if(result != -1) {       //判断返回结果,若结果不为-1,则说明查找成功,即A中有此元素,将此元素加入list中
                *p = a[result];
                p++;
                cout<<result<<"   "<<a[result]<<endl;
            }
    }

    int len_list = get_array_len(list);
    cout<<"A,B中相同的元素个数为:"<<len_list+1<<endl;
    for(int i = 0; i<= len_list; i++){  //将结果打印出来
        cout<<list[i]<<endl;

    }
    delete [] a;
    delete [] b;
    return 0;
}

3、总结:

二分查找是一种效率较高的算法,但是需要给定的数列是有序的。可以结合之后的排序算法一起使用。

猜你喜欢

转载自blog.csdn.net/hhaowang/article/details/83716619