1. 程式人生 > >C++:採用vector實現二分查詢及其變種總結

C++:採用vector實現二分查詢及其變種總結

主要分為六種情況,閉區間,半開區間,中位值在迴圈之外的半開區間二分查詢首個序列,中位值在迴圈之外的半開區間二分查詢末尾序列,以及中位值在迴圈之外的完全開區間二分查詢首個序列和中位值在迴圈之外的完全開區間二分查詢末尾序列:

#include <iostream>
#include <vector>
#include <assert.h>


using namespace std;


// closed interval
int binarySearchClose(vector<int> &invec, int &pos, int &value){
  int low = 0, high = pos-1;
  assert(!invec.empty() && pos>=0);
  while(low <=high){
      int mid = (low+high)/2;
      if(invec[mid] == value){
return mid;
      }
      else if(invec[mid] < value){
low = mid+1;
      }
      else{
high = mid-1;
      }
  }
  return -1;
}


// open interval
int binarySearchOpen(vector<int> &invec, int &pos, int &value){
  int low = 0, high = pos;
  while(low<high){
    int mid = (low+high)/2;
    if(invec[mid] == value){
      return mid;
    }
    else if(invec[mid] < value){
      low = mid+1;
    }
    else{ // invec[mid] >= value
      high = mid;
    }
  }
}
// one improved binary search approach in open interval
int binarySearchOpenImprovedFirst(vector<int> &invec, int &pos, int &value){
  int low = 0, high = pos;
  assert(!invec.empty() && pos>=0);
  while(low<high){
    int mid=(low+high)/2;
    // explain: status 1: when low position is moving, the high position is fixed.
    if(invec[mid]<value){
      low = mid+1;
    }
    //status 2: when high position is moving, the low position is fixed.
    else{ // invec[mid] >= value
      high = mid;
    }
  }
  // the termination condition is high = low
  if(low>=pos || invec[low] != value){
    return -low-1;
  }
  else{
    return low;
  }
}


int binarySearchOpenImprovedLast(vector<int> &invec, int &pos, int &value){
  int low = -1, high = pos-1;
  assert(!invec.empty() && pos >= 0);
  while(low<high){
    //int mid = high - (high-low)/2;
    // int mid = (high+low)/2;
    int mid = (high+low+1)/2; // the above three value
    if(invec[mid]>value){
      high = mid-1;
    }
    else{
      low = mid;
    }
  }
  if(high<0 || invec[high] != value){
    return -high-1;
  }
  else{
    return high;
  }
}


// the complete open interval
int binarySearchCompleteOpenFirst(vector<int> &invec, int &pos, int &value){
  int low = -1, high = pos;
  assert(!invec.empty() || pos >= 0);
  while(low+1<high){
    int mid = (low+high)/2;
    if(invec[mid] < value){
      low=mid;
    }
    else{ // invec[mid] >=value
      high=mid;
    }
  }
  if(high>=pos || invec[high]!= value){
    return -high-1;
  }
  else{
    return high; // high = low+1
  }
}


int binarySearchCompleteOpenLast(vector<int> &invec, int &pos, int &value){
  int low = -1, high = pos;
  while(low+1<high){
    int mid = (low+high)/2;
    if(invec[mid]>value){
      high = mid;
    }
    else{
      low = mid;
    }
  }
  if(low<0 || invec[low] != value){
    return -1;
  }
  else{
    return low; 
  }
  
}


int main(){
  vector<int> invec{1, 3, 3, 3, 3, 3, 3, 15, 19, 19, 19, 20, 20}; // len is 13
  int len = invec.size();
  int value = 20;
  
  //int pos = binarySearchClose(invec, len, value); // search in the closed interval, (when exist duplicate elements ), the find position is random
  
  //int pos = binarySearchOpen(invec, len, value); // search in the open interval, (when exist duplicate elements ), the find position is the last one
  
  //int pos = binarySearchOpenImprovedFirst(invec, len, value); // improved search approach in open interval region, (when exist duplicate elements ), the find position is the first one
  
  int pos = binarySearchOpenImprovedLast(invec, len, value); // improved search approach in open interval region, (when exist duplicate elements ), the find position is the last one
  
  // int pos = binarySearchCompleteOpenFirst(invec, len, value); // (when exist duplicate elements ), the find position is the first one
  
  //int pos = binarySearchCompleteOpenLast(invec, len, value); // (when exist duplicate elements ), the find position is the last one
  
  cout << "the position of the value is : " << pos << endl;
}