// search example. linear and binary search
// bds 10/98
#include <iostream.h>
#include <iomanip.h>
#include <stdlib.h>
#include "tracing.h"

void initialize( float[], int );

template< class T >
T* binarySearch( T searchKey, T* low, T* high );

template< class T >
int linearSearch( T b[], int bSize, T searchKey) ;

int search( float b[], int bSize, float searchKey, float*& index) {

  index = binarySearch( searchKey, b,b+bSize-1);
  return index != b+bSize && *index == searchKey; 

}

int tracing = 0; // false

int main(int argc, char* argv[]) {
   float dataSet[ 1000000 ];
   int size;
   float* index;
   float key;
   int success; // boolean
   if ( argc != 3 ) {
     cout << "usage: " << argv[0] << " dataSetSize numberOfSearches" << endl;
     cout << "If dataSetSize is negative, -dataSetSize used and tracing done."
          << endl;
     return 0;
   }

   size = atoi( argv[1] );
   if ( size < 0 ) { tracing = 1; size = -size; }
   initialize( dataSet, size );

   for (int i = atoi( argv[2] ); i > 0; i--) {
     key = (float) ((rand() * rand())%(2*size));
     success = search( dataSet, size, key, index );
     if (success)
       cout << key << " found at location " << index-dataSet << endl;
     else
       cout << key << " not found at any location" << endl;
   }
}

void initialize( float A[], int s ) {
  for (int i = 0; i < s; i++)
    A[i] = 2*i;
}

/*
void initialize( float A[], int s ) {
  for (int i = 0; i < s; i++)
    A[i] = (float) rand();
}
*/

//// Generic search algorithms

template <class T>
int linearSearch( T b[], int bSize, T searchKey) {
  int location = bSize;
  // implements a linear search process
  for (int i = 0; i < bSize; i++) {
    if (tracing) enter ("linearSearchLoop", i);
    if ( b[i] == searchKey ) {
      location = i;
    }
    if (tracing) exit (NULL, i, location);
  }
  return location; 
}

template< class T >
T* binarySearch( T searchKey, T* low, T* high ) {
// assume: b is sorted in increasing order.
// assert: if searchKey in range b[low] thru b[high] then the 
// index of an occurence of searchKey is returned.
  T* ans;

  if (low == high) ans = low;
  else {
    T* middle = low + (high - low)/2;
    if ( *middle >= searchKey )
      ans = binarySearch( searchKey, low, middle );
    else
      ans = binarySearch( searchKey, middle + 1, high);
  }

  return ans;
}
  
