zoukankan      html  css  js  c++  java
  • 二分查找变体

    从一个循环有序的数组中查找一个元素,如果存在则返回相应位置,否则返回-1.所谓的循环有序是指类似于如下的数组
    10 11 12 1 2 3 4 5 6

    基础代码,供二分查找变体使用

     辅助函数
     1 //二分查找
    2 int Binary_search(int a[],int beg,int end,int val)
    3 {
    4 while(beg<=end)
    5 {
    6 int mid = (beg+end)/2;
    7 if(val==a[mid])
    8 return mid;
    9 if(val>a[mid])
    10 {
    11 beg = mid+1;
    12 }
    13 else
    14 {
    15 end = mid -1;
    16 }
    17 }
    18 return -1;
    19 }
    20
    21 //顺序查找
    22 int Search(int a[],int beg,int end,int val)
    23 {
    24 cout<<"Search!"<<endl;
    25 while(beg<=end)
    26 {
    27 if(a[beg]==val)
    28 return beg;
    29 ++beg;
    30 }
    31 return -1;
    32 }

    二分查找代变体改进版核心代码:

     第一版代码
    int Binary_search(int a[],int size,int val)
    {
    int beg=0;
    int end=size -1;
    while(beg<=end)
    {
    int mid = (beg+end)/2;
    if(val == a[mid])
    return mid;
    if(val>a[mid])
    {
    if(val<=a[end])
    {
    if(val == a[end])
    return end;
    return Binary_search(a,mid+1,end-1,val);
    }
    if(a[mid]>a[size-1])
    {
    beg =mid+1 ;
    }
    else if (a[mid]<a[size-1])
    {
    end = mid -1;
    }
    else
    {
    return Search(a,beg+1,end-1,val);
    }
    }
    else
    {
    if(val>=a[beg])
    {
    if(val == a[beg])
    return beg;
    return Binary_search(a,beg+1,mid-1,val);
    }

    if(a[mid]>a[0])
    {
    beg =mid +1;
    }
    else if (a[mid]<a[0])
    {
    end = mid -1;
    }
    else
    {
    return Search(a,beg+1,end-1,val);
    }
    }
    }
    return -1;
    }

    改进版代码:

    改进版本代码
     1 int Binary_search(int *arr,int const size,int const val)
    2 {
    3 if(arr[0] ==val)
    4 return 0;
    5 int beg =1;
    6 int end = size -1;
    7 int const iFirst =arr[0];
    8 int const iLast = arr[size-1];
    9 int const iMid = (beg+end)/2;
    10 while(beg<=end)
    11 {
    12 int mid = (beg+end)/2;
    13 if(arr[mid] == val)
    14 return mid;
    15
    16 //左边有序,如果在左边的范围内,直接二分查找,否则到右边去找
    17 if(arr[mid]>iFirst)
    18 {
    19 if(val>=arr[beg]&&val<arr[mid])
    20 {
    21 return Binary_search(arr,beg,mid-1,val);
    22 }
    23 beg = mid+1;
    24 }
    25 //右边有序,如果在右边的范围内,直接二分查找,否则在左边去找
    26 else if(arr[mid]<iFirst)
    27 {
    28 if(val>arr[mid]&&val<=iLast)
    29 {
    30 return Binary_search(arr,mid+1,end,val);
    31 }
    32 end = mid -1;
    33 }
    34 else
    35 {
    36 //iFirst=arr[mid]>iLast左边为有序且恒等的一个序列,在右边找
    37 if(arr[mid]>iLast)
    38 {
    39 beg = mid+1;
    40 }
    41 else //arr[mid]==iFirst>=iLast,arr[min]不可能小于iLast,在这里arr[min] == iLast = iFirst
    42 {
    43 if(mid>iMid) //iMid左边是个递增数列,arr[iMid]>arr[min];mid的右边是恒等序列
    44 {
    45 end = mid -1;
    46 }
    47 else if(mid<iMid)//iMid右边是个递增序列,arr[iMid]<arr[min],min的左边是恒等序列
    48 {
    49 beg = mid+1;
    50 }
    51 else
    52 {
    53 return Search(arr,beg,end,val);
    54 }
    55 }
    56 }
    57 }
    58 return -1;
    59 }

    测试代码

    测试代码
     1 #include<iostream>
    2 #include <cstdlib>
    3 #include <ctime>
    4 #include<algorithm>
    5 using namespace std;
    6 void Reverse(int * beg,int *end)
    7 {
    8 while(beg<end)
    9 {
    10 swap(*beg,*end);
    11 ++beg;
    12 --end;
    13 }
    14 }
    15
    16 void Move(int *arr,int size, int pos)
    17 {
    18 Reverse(arr,arr+size-1);
    19 Reverse(arr,arr+pos);
    20 Reverse(arr+pos+1,arr+size-1);
    21 }
    22
    23 void Check(int *arr,int size)
    24 {
    25 bool bTrue =true;
    26 for(int i=1;i<size;++i)
    27 {
    28 if(arr[i]<arr[i-1])
    29 {
    30 if(!bTrue)
    31 cout<<"Check Failed!"<<endl;
    32 bTrue = false;
    33 }
    34 }
    35 if(bTrue)
    36 cout<<"Check Failed!"<<endl;
    37 }
    38 int main(int argc, char* argv[])
    39 {
    40 srand(time(0));
    41 int const size = 10001;
    42 int *arr = new int[size];
    43 for(int test=0;test<1000;++test)
    44 {
    45 for(int i =0;i<size;++i)
    46 {
    47 arr[i] = rand()%100;
    48 }
    49 sort(arr,arr+size);
    50 int pos = 1+ rand()%(size-10);
    51 Move(arr,size,pos);
    52 Check(arr,size);
    53 for(int i=0;i<size;++i)
    54 {
    55 int iIndex = Binary_search(arr,size,arr[i]);
    56 if(iIndex==-1)
    57 {
    58 cout<<"Wrong1";
    59 return 0;
    60 }
    61 if(arr[iIndex]!=arr[i])
    62 {
    63 cout<<"Wrong2";
    64 return 0;
    65 }
    66 }
    67 }
    68
    69 return 0;
    70 }




  • 相关阅读:
    JAVA单例MongoDB工具类
    Docker的安装使用-第1章
    JSON支持什么对象/类型?
    Linux环境源码编译安装SVN
    网站优化总结
    [java]反射1 2017-06-25 21:50 79人阅读 评论(10) 收藏
    记一次问题的解决,web自动化用例的管理
    将GatlingBundle容器化,并通过参数化来执行压测
    基于Fitnesse的接口自动化测试-关键字设计-样例-mysql操作
    基于Fitnesse的接口自动化测试-关键字设计-样例-redis操作
  • 原文地址:https://www.cnblogs.com/SammyLan/p/2205904.html
Copyright © 2011-2022 走看看