LAB 8: SEARCHING ALGORITHMS

advertisement
LAB 8: SEARCHING ALGORITHMS
Exercise 1 Use a Binary Search Technique
Problem statement:
Use a binary search technique to rewrite the guess_game function from Figure
1.4 on page 24 of your text. The function may ask questions such as “Is your
number bigger than 42?” Your result should have worst-case time of 0(log n).
Learning Objectives:
The learner will be able to:
Modify an existing function to use a binary search technique.
Exercise 2 Double Hashing
Problem statement:
Use double hashing to re-implement the hash table from Figure 12.4 on page 596.
Learning Objectives:
The learner will be able to:
Implement a hash table using the double hashing technique.
Equipment:
Typical Computer Lab setup
Components/Materials:
Microsoft Visual C++
Classroom Configuration:
N/A
1
Lab Handout for IT327
Data Structures
Lab Procedures:
Complete the following tasks: Exercise 1
1. Use a binary search technique to rewrite the guess_game function from Figure 1.4
on page 24 of your text.
2. The function may ask questions such as “Is your number bigger than 42?”
3. Your result should have worst-case time of 0(log n).
Complete the following tasks: Exercise 2
Use double hashing to re-implement the hash table from Figure 12.4 on page 596.
Validation/Evaluation
Answers to Lab Exercises
Solutions to Lab Exercises can be found at the Curriculum Knowledge Network
(CKN) section of the ITT Technical Institute Employee Portal, http://myportal.itttech.edu. The solutions are also listed below.
Exercise 1
// FILE: guess.cpp
// From Chapter 1 of Data Structures and Other Objects (Third Edition)
//
_____________________________________________________________________
//
// This file has been modified to work with Microsoft Visual C++ 6.0,
// as described in www.cs.colorado.edu/~main/vc6.html
// Modifications:
// -- File name changed to guess.cpp
//
_____________________________________________________________________
//
// Demostrates a guessing game function that's used as a time analysis example.
#include <cassert>
#include <iostream>
#include <cstdlib>
using namespace std;
// Provides assert
// Provides cout and cin
// Provides EXIT_SUCCESS
// Allows all Standard Library items to be used
// Prototype for the function used in this demonstration program
void guess_game(int n);
// Precondition: n > 0.
// Postcondition: The user has been asked to think of a number between 1 and n.
// The function asks a series of questions, until the number is found.
2
Lab Handout for IT327
Data Structures
int main( )
{
guess_game(100);
return EXIT_SUCCESS;
}
void guess_game(int n)
// Library facilities used: cassert, iostream
{
int guess;
char answer;
assert(n >= 1);
cout << "Think of a whole number from 1 to " << n << "." << endl;
answer = 'N';
for (guess = n; (guess > 0) && (answer != 'Y') && (answer != 'y'); --guess)
{
cout << "Is your number " << guess << "?" << endl;
cout << "Please answer Y or N, and press return: ";
cin >> answer;
}
if ((answer == 'Y') || (answer == 'y'))
cout << "I knew it all along." << endl;
else
cout << "I think you are cheating!" << endl;
}
// FILE: search.cxx
// Demonstration program for the binary search function
#include <cstdlib> // Provides EXIT_SUCCESS, size_t
#include <iostream> // Provides cin, cout
using namespace std;
// PROTOTYPE for function used in demonstration program:
void search(
const int a[ ],
size_t first,
size_t size,
int target,
bool& found,
size_t& location
);
3
Lab Handout for IT327
Data Structures
int main( )
{
const size_t MANY = 10;
int fibonacci[MANY] = { 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 };
int target;
bool found;
size_t location;
do
{
cout << "Please type an integer from 0 to 100: ";
cin >> target;
}
while ((target < 0) || (target > 100));
search(fibonacci, 0, MANY, target, found, location);
if (found)
cout << target << " is a Fibonacci number at ["
<< location << "] in my array." << endl;
else
cout << target << " is not a Fibonacci number." << endl;
return EXIT_SUCCESS;
}
void search(
const int a[ ],
size_t first,
size_t size,
int target,
bool& found,
size_t& location
)
// Precondition: The array segment starting at a[first] and containing size
// elements is sorted from smallest to largest.
// Postcondition: The array segment starting at a[first] and containing size
// elements has been searched for the target. If the target was present, then
// found is true, and location is set so that target == a[location];
// Otherwise, found is set to false.
// Library facilities used: stdlib.h (provides size_t).
{
size_t middle;
if (size == 0)
found = false;
else
4
Lab Handout for IT327
Data Structures
{
middle = first + size/2;
if (target == a[middle])
{
location = middle;
found = true;
}
else if (target < a[middle])
// The target is less than a[middle], so search before the middle
search(a, first, size/2, target, found, location);
else
// The target must be greater than a[middle], so search after the middle
search(a, middle+1, (size-1)/2, target, found, location);
}
}
Exercise 2
// FILE: table1.h (part of the namespace main_savitch_12A)
// From Chapter 12 of Data Structures and Other Objects (Third Edition)
//
_____________________________________________________________________
//
// This file has been modified to work with Microsoft Visual C++ 6.0,
// as described in www.cs.colorado.edu/~main/vc6.html
//
_____________________________________________________________________
//
// TEMPLATE CLASS PROVIDED: table<RecordType> (a table of records with
keys).
// This class is a container template class for a table of records.
// The template parameter, RecordType, is the data type of the records in the
// table. It may be any of the bulit-in C++ types (int, char, etc.), or a
// class with a default constructor, an assignment operator, and an integer
// member variable called key.
//
// MEMBER CONSTANT for the table<RecordType> class:
// static const size_type CAPACITY = ________
// table<RecordType>::CAPACITY is the maximum number of records held by a
table.
//
// CONSTRUCTOR for the table<RecordType> template class:
// table( )
// Postcondition: The table has been initialized as an empty table.
//
// MODIFICATION MEMBER FUNCTIONS for the table<RecordType> class:
5
Lab Handout for IT327
Data Structures
// void insert(const RecordType& entry)
// Precondition: entry.key >= 0. Also if entry.key is not already a key in
// the table, then the table has space for another record
// (i.e., size( ) < CAPACITY).
// Postcondition: If the table already had a record with a key equal to
// entry.key, then that record is replaced by entry. Otherwise, entry has
// been added as a new record of the table.
//
// void remove(int key)
// Postcondition: If a record was in the table with the specified key, then
// that record has been removed; otherwise the table is unchanged.
//
// CONSTANT MEMBER FUNCTIONS for the table<RecordType> class:
// bool is_present(const Item& target) const
// Postcondition: The return value is true if there is a record in the
// table with the specified key. Otherwise, the return value is false.
//
// void find(int key, bool& found, RecordType& result) const
// Postcondition: If a record is in the table with the specified key, then
// found is true and result is set to a copy of the record with that key.
// Otherwise found is false and the result contains garbage.
//
// size_type size( ) const
//
Postcondition: Return value is the total number of records in the
//
table.
//
// VALUE SEMANTICS for the table<RecordType> template class:
// Assignments and the copy constructor may be used with table objects.
#ifndef TABLE1_H
#define TABLE1_H
#include <cstdlib> // Provides size_t
namespace main_savitch_12A
{
template <class RecordType>
class table
{
public:
// * For VC++ 6.0 we are using size_t instead of std::size_t. And we
// * have defined CAPACITY using an enum instead of a static member
// * constant. See www.cs.colorado.edu/~main/vc6.html for details.
enum { CAPACITY = 30 };
// CONSTRUCTOR
table( );
// MODIFICATION MEMBER FUNCTIONS
6
Lab Handout for IT327
Data Structures
void insert(const RecordType& entry);
void remove(int key);
// CONSTANT MEMBER FUNCTIONS
bool is_present(int key) const;
void find(int key, bool& found, RecordType& result) const;
size_t size( ) const { return used; }
private:
// MEMBER CONSTANTS -- These are used in the key field of special records.
enum { NEVER_USED = -1 };
enum { PREVIOUSLY_USED = -2 };
// MEMBER VARIABLES
RecordType data[CAPACITY];
size_t used;
// HELPER FUNCTIONS
size_t hash(int key) const;
size_t next_index(size_t index) const;
void find_index(int key, bool& found, size_t& index) const;
bool never_used(size_t index) const;
bool is_vacant(size_t index) const;
};
}
#include "table1.template" // Include the implementation.
#endif
// FILE: table1.template
// From Chapter 12 of Data Structures and Other Objects (Third Edition)
//
_____________________________________________________________________
//
// This file has been modified to work with Microsoft Visual C++ 6.0,
// as described in www.cs.colorado.edu/~main/vc6.html
//
_____________________________________________________________________
//
// TEMPLATE CLASS IMPLEMENTED: table (see table1.h for documentation)
// INVARIANT for the table ADT:
// 1. The number of records in the table is in the member variable used.
// 2. The actual records of the table are stored in the array data, with
//
a maximum of CAPACITY entries. Each used spot in the array has a
//
non-negative key. Any unused record in the array has a key field of
//
NEVER_USED (if it has never been used) or PREVIOUSLY_USED (if it once
//
was used, but is now vacant).
#include <cassert> // Provides assert
#include <cstdlib> // Provides size_t
7
Lab Handout for IT327
Data Structures
namespace main_savitch_12A
{
// MEMBER CONSTANTS
*********************************************:
// Not needed for VC++ 6.0
/*
template <class RecordType>
const size_t table<RecordType>::CAPACITY;
template <class RecordType>
const int table<RecordType>::NEVER_USED;
template <class RecordType>
const int table<RecordType>::PREVIOUSLY_USED;
*/
template <class RecordType>
table<RecordType>::table( )
{
size_t i;
used = 0;
for (i = 0; i < CAPACITY; ++i)
data[i].key = NEVER_USED; // Indicates a spot that's never been used.
}
template <class RecordType>
void table<RecordType>::insert(const RecordType& entry)
// Library facilities used: cassert
{
bool already_present; // True if entry.key is already in the table
size_t index;
// data[index] is location for the new entry
assert(entry.key >= 0);
// Set index so that data[index] is the spot to place the new entry.
find_index(entry.key, already_present, index);
// If the key wasn't already there, then find the location for the new entry.
if (!already_present)
{
assert(size( ) < CAPACITY);
index = hash(entry.key);
while (!is_vacant(index))
index = next_index(index);
++used;
8
Lab Handout for IT327
Data Structures
}
data[index] = entry;
}
template <class RecordType>
void table<RecordType>::remove(int key)
// Library facilities used: cassert
{
bool found;
// True if key occurs somewhere in the table
size_t index; // Spot where data[index].key == key
assert(key >= 0);
find_index(key, found, index);
if (found)
{ // The key was found, so remove this record and reduce used by 1.
data[index].key = PREVIOUSLY_USED; // Indicates a spot that's no longer
in use.
--used;
}
}
template <class RecordType>
bool table<RecordType>::is_present(int key) const
// Library facilities used: assert.h
{
bool found;
size_t index;
assert(key >= 0);
find_index(key, found, index);
return found;
}
template <class RecordType>
void table<RecordType>::find(int key, bool& found, RecordType& result) const
// Library facilities used: cassert.h
{
size_t index;
assert(key >= 0);
find_index(key, found, index);
if (found)
9
Lab Handout for IT327
Data Structures
result = data[index];
}
template <class RecordType>
inline size_t table<RecordType>::hash(int key) const
{
return (key % CAPACITY);
}
template <class RecordType>
inline size_t table<RecordType>::next_index(size_t index) const
// Library facilities used: cstdlib
{
return ((index+1) % CAPACITY);
}
template <class RecordType>
void table<RecordType>::find_index(int key, bool& found, size_t& i) const
// Library facilities used: cstdlib
{
size_t count; // Number of entries that have been examined
count = 0;
i = hash(key);
while((count < CAPACITY) && (data[i].key != NEVER_USED) &&
(data[i].key != key))
{
++count;
i = next_index(i);
}
found = (data[i].key == key);
}
template <class RecordType>
inline bool table<RecordType>::never_used(size_t index) const
{
return (data[index].key == NEVER_USED);
}
template <class RecordType>
inline bool table<RecordType>::is_vacant(size_t index) const
{
return (data[index].key == NEVER_USED) || (data[index].key ==
PREVIOUSLY_USED);
}
}
10
Lab Handout for IT327
Data Structures
Download