数据结构--杂记-二分查找

  • 介绍二分查找之前,首先看看简单的数值比较的两种实现;

    • 数值比较是简单的if-else-if语句的使用,先看看函数版本的实现:
    int compare(int a,int b){
        if(x<y) return -1;
        else if(x==y)return 0;
        else return 1;
    }   
    • 上面的程序在处理int类型的数据,进行比较大小是没有错误的,在绝大多数情况下是可以运行的;
    • 数值比较的宏实现方式;
    define COMPARE(x,y) (((x)<(y)) ? -1 :((x)==(y)) ? 0:1)
    • 使用宏实现的大小比较,在处理float,double的数值时是有点小问题的;
    • 浮点数在计算机的存储和整形的存储是不太一样的,对于小数点后面的数字每一位分别表示1/2,1/4,1/8,1/16,浮点数的存储实际上采用的是微分的思想,也就是在无限进行数值的逼近,对于绝大多数浮点数都是可以准确进行存储并且进行比较的;
    • float浮点数在进行存储过程中的一个程序验证;
int main(){
    float lk=2.424523525566476667;
    printf("%f\n",lk);  

    double llk=2.42452352556647667;
    printf("%f\n",llk);
}
  • 输出结果是:
    这里写图片描述

  • 在进行浮点数的保存和输出过程中,其实是进行了四射五入的,当然不同的编译器对于这个处理也是不同的,这只是数值存储的一种情况,特殊的在整理之后再发;

    • 为了防止特殊情况的发生,浮点数的比较应该采用阀值的思想来进行相等性的比较;
//这里是用compare变量来允许用户在进行浮点数的比较时,可以传入一个阀值来判断两个浮点数是否相等;

int compare(float a,float b,float compare)
{
    if(a<b) return -1;
//fabs()如果是浮点数绝对值函数使用fabs(),如果是整型使用函数abs();
    else if(fabs(a-b)<compare) return 0;
    else return 1;
}
  • 分析二分查找算法执行过程:

    • 1.首先函数原型需要传递的参数包括:array[],searchnum,left,right,四个参数的意思分别是查找的有序数组,需要查找数值,查找的左边界,查找的右边界;
    • 2.对于查找的过程包括三种情况:
      • 1.searchnum<array[middle]:就应该在有序数组的左边进行查找,需要改变right的值:right=middle-1
      • 2.searchnum==array[middle]找到的数据就是需要的数据,那么直接进行返回:return middel;
      • 3.searchnum>array[middle]:说明查找的数值应该在数值的右半本部分,所以应该改变left=middle+1
  • Binary_search()的实现:

#include <stdlib.h>
#include <stdio.h>
#include "Mystd.h"
int Compare(int left, int right, int compare)
{
    if (left < right) return -1;
    else if (abs(left - right) < compare) return 0;
    else return 1;
}

int Binary_search(int array[], int SearchNumber, int left, int right)
{
    if (array == NULL || left == right)
        exit;
    int middle = 0;
    while (left <= right)
    {
        middle = (left + right) / 2;
        switch (Compare(array[middle], SearchNumber, 1))
        {
        case -1:
            left = middle + 1;
            break;
        case 0:
            return middle;
        case 1:
            right = middle - 1;
        }

    }
    return -1;

}

int main()
{
    int myarray[] = {1, 6, 9, 0, 3, 6, 5,3, 1, 7, 6, 9, 4};
    choice_sort(myarray,sizeof(myarray)/sizeof(int));
    size_t i=0;
    for( i=0;i<sizeof(myarray)/sizeof(int);++i)
        printf("%d ",myarray[i]);
    printf("\n");

    int k = Binary_search(myarray,3,0,sizeof(myarray)/sizeof(int));
    if(k==-1)
        printf("Not found!!");
    else
        printf("Found it at: %d \n",k);

     k = Binary_search(myarray,3,0,k);
    if(k==-1)
        printf("Not found!!");
    else
        printf("Found it at: %d \n",k);
}
  • 程序的执行结果
    这里写图片描述
  • Binary_Search对于没有重复元素的查找是没有丝毫问题的,这里尝试处理的的是具有重复元素的查找过程;
  • 由执行结果看一个看出,程序首先找出了最右边的3位置是4,然后再修正之后,才找到了左边的三,如果在修正过程中发生错误,那么左边的3很有可能找不到;
  • 来看看这种情况是如何发生的:
    这里写图片描述

  • 对于这个这种情况可以使用C++STL来进行尝试;

int main(){
    vector<int>  myarry={1,6,9,0,3,6,5,3,1,7,9,4};
    sort(myarry.begin(),myarry.end());
    auto it =binary_search(myarry.begin(),myarry.end(),3);
    if(it==0)
        cout << "Not found\n";
    else
        cout << "Find position: " << it << endl;
}

*使用C++STL提供的Binary_search仅仅可以查看是否有这个元素,如果需要得到元素的位置还需要这样;


int main()
{
    vector<int>  mytins = {1, 6, 9, 0, 3, 6, 5, 3, 1, 7, 9, 4};
    pair<vector<int>::iterator, vector<int>::iterator> bounds;

    sort(mytins.begin(), mytins.end());
    bounds = equal_range(mytins.begin(), mytins.end(), 3);
    cout << "bounds at positions " << (bounds.first - mytins.begin());
    cout << " and " << (bounds.second - mytins.begin()) << endl;
}
  • 代码的执行结果是:
    这里写图片描述

  • 这种方式的查找对于两个重复元素的查找是比较有效的,对于更多的重复元素还需要进行实验,在总结之后在整理;

  • 对于二分查找时间复杂度是log2 n,查找元素还是很快速的;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值