|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T s
Length: 5806 (0x16ae)
Types: TextFile
Names: »search.cc«
└─⟦a05ed705a⟧ Bits:30007078 DKUUG GNU 2/12/89
└─⟦cc8755de2⟧ »./libg++-1.36.1.tar.Z«
└─⟦23757c458⟧
└─⟦this⟧ »libg++/etc/search.cc«
// From: "Douglas C. Schmidt" <schmidt@blanche.ics.uci.edu>
// Date: Sat, 29 Oct 88 14:11:51 -0700
#include <stream.h>
/**********************************************************************/
/**********************************************************************/
typedef int ITEM_TYPE;
class Additive_Search
{
// Implements the binary search variation described on pages 138 and 139
// of Tim Standish's ``Data Structure Techniques'' textbook. The big
// win here is that this version uses no division (or right shift),
// only addition, so it runs faster on most computers.
private:
ITEM_TYPE *Vector_Buffer; // Hold's copy of the initialized search structure
int Vector_Length; // Length of the user's input
static int Tree_Height; // Height of the implicit binary search tree
static ITEM_TYPE *Temp; // Temporary storage during initialization
void Fill_Buffer (int h, int i); // Transforms sorted array into special
// representation that supports the
// additive binary search technique
public:
Additive_Search (ITEM_TYPE *Array, int Len);
int Is_Member (ITEM_TYPE K);
~Additive_Search (void);
};
/**********************************************************************/
void Additive_Search::Fill_Buffer (int Hgt, int Index)
{
// Uses a very concise recursive routine to initialize the Vector_Buffer from
// the original sorted array (which must have been sorted, or else this
// *won't* work)! This magic sequence of statements transforms the original sorted
// array into an new array representing the level order traversal of a complete
// binary search tree. See Standish, page 138 for details...
if ((Hgt <= Tree_Height) && (Index < Vector_Length))
{
Fill_Buffer (Hgt + 1, (Index + Index) + 1);
Vector_Buffer [Index] = *Temp++;
Fill_Buffer (Hgt + 1, (Index + Index) + 2);
}
}
/**********************************************************************/
Additive_Search::Additive_Search (ITEM_TYPE *Array, int Len)
{
Tree_Height = lg (Len);
Vector_Length = Len;
Temp = Array;
Vector_Buffer = new ITEM_TYPE [Len];
Fill_Buffer (0, 0); // Tree_Height and Index both start off at 0
}
/**********************************************************************/
int
Additive_Search::Is_Member (ITEM_TYPE K)
{
// Performs the additive binary search upon the initialized Vector_Buffer.
// Note that we perform no division or multiplication in this search.
// Such omissions generally yield faster running times on most machines.
register int i = 0;
while (i < Vector_Length)
{
register int Cmp = (Vector_Buffer [i] - K);
if (Cmp == 0)
return 1;
else
{
i += i + 1;
if (Cmp < 0)
i++;
}
}
return 0;
}
/**********************************************************************/
Additive_Search::~Additive_Search (void)
{
delete Vector_Buffer;
}
/**********************************************************************/
/**********************************************************************/
class Binary_Search
{
// Performs the typical binary search algorithm. For comparison purposes only.
#define COPY(DEST,SRC,NB) {register typeof(DEST) a = (DEST), b = (SRC);\
register int i, j = (NB);\
for (i = (j & 07)+1; --i;) *a++ = *b++;\
for (i = (j>>3)+1; --i>0;) {\
*a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++;\
*a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++;\
}}
private:
ITEM_TYPE *Vector_Buffer;
int Vector_Length;
public:
Binary_Search (ITEM_TYPE *Array, int Len): Vector_Length (Len)
{
Vector_Buffer = new ITEM_TYPE [Len];
COPY (Vector_Buffer, Array, Len); // The infamous Duff's Device!
}
int Is_Member (ITEM_TYPE K)
{ // Yawn, this looks familiar
register int hi;
register int lo;
for (lo = 0, hi = Vector_Length - 1; lo <= hi ;)
{
register int mid = (lo + hi) >> 1;
if (Vector_Buffer [mid] == K)
return 1;
else if (Vector_Buffer [mid] < K)
lo = mid + 1;
else
hi = mid - 1;
}
return 0;
}
~Binary_Search (void)
{
delete Vector_Buffer;
}
};
/**********************************************************************/
static int Cmp (void *A, void *B)
{ // Too bad we lack lambdas!
return (*(ITEM_TYPE*)A < *(ITEM_TYPE*)B)?
-1 :
((*(ITEM_TYPE*)A == *(ITEM_TYPE*)B) ? 0 : 1);
}
/**********************************************************************/
double return_elapsed_time (double);
double start_timer (void);
void Gen_Rand (ITEM_TYPE Buf[], int Size);
int main (int, char *argv[])
{
int Size = atoi (argv [1]);
ITEM_TYPE Buf [Size];
Gen_Rand (Buf, Size);
qsort ((void *) Buf, Size, sizeof (ITEM_TYPE), Cmp);
Additive_Search Foo (Buf, Size);
Binary_Search Bar (Buf, Size);
start_timer ();
for (int i = 0; i < Size ; i++)
if (! Bar.Is_Member (Buf [i]))
cout << "bad news, buf [" << i << "] = " << Buf [i] << "!\n";
double Elapsed_Time = return_elapsed_time (0.0);
cout << "Binary Time = " << Elapsed_Time << "\n";
start_timer ();
for (i = 0; i < Size ; i++)
if (! Foo.Is_Member (Buf [i]))
cout << "bad news, buf [" << i << "] = " << Buf [i] << "!\n";
Elapsed_Time = return_elapsed_time (0.0);
cout << "Additive Time = " << Elapsed_Time << "\n";
return 0;
}
void Gen_Rand (ITEM_TYPE Buf[], int Size)
{ // Generates some random numbers
srandom (getpid ());
for (int i = 0; i < Size; i++)
Buf [i] = ITEM_TYPE (random ());
}