-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
462 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,202 @@ | ||
#ifndef DEQUE_AS_ARRAY_H | ||
#define DEQUE_AS_ARRAY_H | ||
#include <iostream> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <cmath> // std::abs | ||
#include "Exception.h" | ||
#include <math.h> | ||
#include <algorithm> | ||
|
||
class Deque_as_array { | ||
private: | ||
int array_size; | ||
int*array; | ||
int ihead; | ||
int itail; | ||
int count; | ||
|
||
public: | ||
//Member function declarations | ||
Deque_as_array( int = 10 ); //default array size | ||
~Deque_as_array(); //The de-constructor | ||
|
||
//Accessors | ||
int head() const; | ||
int tail() const; | ||
int size() const; | ||
bool empty() const; | ||
int capacity() const; | ||
|
||
//Mutators | ||
void enqueue_head( | ||
int const & ); | ||
void enqueue_tail( int const & ); | ||
int dequeue_head(); | ||
int dequeue_tail(); | ||
void clear(); | ||
void print(); | ||
|
||
|
||
}; | ||
|
||
//The constructor | ||
// -create an instance of the deque by | ||
/* 1. Initializing memory for a deque of the given capacity, and | ||
2. Allocating memory for a deque of the given capacity, and | ||
3 Initializing the deque size to 0 | ||
*/ | ||
Deque_as_array::Deque_as_array( int n ): | ||
array_size( std::max( 1, n ) ), | ||
array( new int[array_size] ), | ||
count( 0 ) { | ||
if( array_size <= 0 ){ | ||
array_size = 1; | ||
} | ||
ihead = -1; | ||
itail = ihead; | ||
} | ||
|
||
/* The de-constructor | ||
DELETE EVERYTHING AND BE FREE | ||
De-allocate the memory made for array */ | ||
Deque_as_array::~Deque_as_array() { | ||
delete [] array; | ||
} | ||
|
||
/* Return the number of entires in the deque | ||
count is the number of objects in the deque */ | ||
int Deque_as_array::size() const { | ||
return count; | ||
} | ||
|
||
/* Return the number of size in the deque | ||
array_size is the declared size for the deque */ | ||
int Deque_as_array::capacity() const { | ||
return array_size; | ||
} | ||
|
||
/* Return if is the deque is empty | ||
See if there are no elements in the deque, then returns true. | ||
False if there are elements */ | ||
bool Deque_as_array::empty() const { | ||
return (count == 0); | ||
} | ||
|
||
/* Check if empty, if not, return the head element (an integer) in the deque | ||
If the dequeu is empty, then head = -1, so an underflow error will be thrown */ | ||
int Deque_as_array::head() const { | ||
if ( empty() ){ | ||
throw underflow(); | ||
} | ||
return array[ihead]; | ||
} | ||
|
||
/* Checks if empty, if not, return the tail element (an integer) in the deque | ||
If the dequeu is empty, then tail = head = -1, | ||
so an underflow error will be throw */ | ||
int Deque_as_array::tail() const { | ||
if ( empty() ){ | ||
throw underflow(); | ||
} | ||
return array[itail]; | ||
} | ||
|
||
/* This function will add an element to the head of the deque | ||
To be consistent with constant time, a circle array is used | ||
Head will initially be 0 then 9 and 8 and goes down | ||
After the element has been added,count goes up by 1 (one new element is added) | ||
If the count is equal to the array_size ( max capacity ) | ||
then my deque is full and an overflow will be thrown */ | ||
void Deque_as_array::enqueue_head( int const &obj ) { | ||
if ( count == (array_size) ){ | ||
throw overflow(); | ||
} | ||
if( empty() ){ | ||
ihead = 0; | ||
itail = ihead; | ||
} else { | ||
ihead = (array_size + ihead - 1) % array_size; | ||
} | ||
array[ihead] = obj; | ||
count++; | ||
} | ||
|
||
/* This function will add an element to the tail of the deque | ||
To be consistent with constant time, a circle array is used | ||
Head will initially be 0 then 1 and 2 and goes up | ||
After the element has been added,count goes up by 1 (one new element is added) | ||
If the count is equal to the array_size ( max capacity ) | ||
then my deque is full and an overflow will be thrown */ | ||
void Deque_as_array::enqueue_tail( int const &obj ) { | ||
if ( count >= (array_size) ){ | ||
throw overflow(); | ||
} | ||
if ( empty() ){ | ||
ihead = 0; | ||
itail = ihead; | ||
} else { | ||
itail = (array_size + itail + 1) % array_size; | ||
} | ||
array[itail] = obj; | ||
count++; | ||
} | ||
|
||
/* This function will remove an element from the head of the deque | ||
To be consistent with constant time, a circle array is used | ||
The head element will be store in a variable called removedHead | ||
Then ihead is moved. Since enqueue_head decreases 0, 9, 8 ... then | ||
ihead will be added be ++ihead%mod array_size (eg. 6 then 7, 8...) | ||
After the element has been removed,count down up by 1 (one element is added) | ||
Then the removedHead is returned | ||
If the count is equal to 0 | ||
then my deque is empty and an underflow will be thrown */ | ||
int Deque_as_array::dequeue_head() { | ||
if ( count <= 0 ){ | ||
throw underflow(); | ||
} | ||
int removedHead = array[ihead]; | ||
ihead = (++ihead) % array_size; | ||
--count; | ||
return removedHead; | ||
} | ||
|
||
/* This function will remove an element from the tail of the deque | ||
To be consistent with constant time, a circle array is used | ||
The tail element will be store in a variable called removedTail | ||
Then itail is moved. Since enqueue_tail is increasing 0, 1, 2 ... then | ||
itail will be subtracted --itail%mod array_size eg. 6 then 5, 4... | ||
To make sure we don't have a negative itail, I added array_size to itail | ||
After the element has been removed,count down up by 1 (one element is added) | ||
removedTail is returned | ||
If the count is equal to 0 | ||
then my deque is empty and an underflow will be thrown */ | ||
int Deque_as_array::dequeue_tail() { | ||
if ( count <= 0 ){ | ||
throw underflow(); | ||
} | ||
int removedTail = array[itail]; | ||
itail = (array_size + itail - 1) % array_size; | ||
--count; | ||
return removedTail; | ||
} | ||
|
||
|
||
void Deque_as_array::print() { | ||
for (int x = 0; x < array_size; x++){ | ||
std::cout << array[x] << std::endl; | ||
} | ||
} | ||
|
||
/* This function will set all count ( number of elements in my deque to 0) | ||
By setting count to 0, it is almost like saying that my deque is empty | ||
However memory is still allocated | ||
Making count to 0, this will not let my accessor access elements in my deque | ||
because exception based on count will be thrown */ | ||
void Deque_as_array::clear() { | ||
count = 0; | ||
ihead = -1; | ||
ihead = itail; | ||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
#ifndef DOUBLE_HASH_TABLE_H | ||
#define DOUBLE_HASH_TABLE_H | ||
#include "Exception.h" | ||
#include "ece250.h" | ||
|
||
enum state { EMPTY, OCCUPIED, DELETED }; | ||
|
||
template<typename T> | ||
class DoubleHashTable { | ||
private: | ||
int count; | ||
int power; | ||
int array_size; | ||
T *array; | ||
state *array_state; | ||
|
||
int h1( T const & ) const; // first hash function | ||
int h2( T const & ) const; // second hash function | ||
|
||
public: | ||
DoubleHashTable( int = 5 ); | ||
~DoubleHashTable(); | ||
int size() const; | ||
int capacity() const; | ||
bool empty() const; | ||
bool member( T const & ) const; | ||
T bin( int ) const; | ||
|
||
void print() const; | ||
|
||
void insert( T const & ); | ||
bool remove( T const & ); | ||
void clear(); | ||
}; | ||
|
||
template<typename T > | ||
DoubleHashTable<T >::DoubleHashTable( int m ): | ||
count( 0 ), power( m ), | ||
array_size( 1 << power ), | ||
array( new T [array_size] ), | ||
array_state( new state[array_size] ) { | ||
|
||
for ( int i = 0; i < array_size; ++i ) { | ||
array_state[i] = EMPTY; | ||
} | ||
} | ||
|
||
template<typename T > | ||
DoubleHashTable<T >::~DoubleHashTable() { | ||
delete [] array; | ||
delete [] array_state; | ||
} | ||
|
||
template<typename T > | ||
int DoubleHashTable<T >::size() const { | ||
return count; | ||
} | ||
|
||
template<typename T > | ||
int DoubleHashTable<T >::capacity() const { | ||
return array_size; | ||
} | ||
|
||
|
||
|
||
template<typename T > | ||
bool DoubleHashTable<T >::empty() const { | ||
return (count == 0); | ||
} | ||
|
||
template<typename T > | ||
int DoubleHashTable<T >::h1( T const &obj ) const { | ||
int index1 = 0; | ||
index1 = static_cast<int>(obj) % array_size; | ||
if (index1 < 0){ | ||
index1 += array_size; | ||
} | ||
|
||
return index1; | ||
} | ||
|
||
template<typename T > | ||
int DoubleHashTable<T >::h2( T const &obj ) const { | ||
int index2 = 0; | ||
index2 = (static_cast<int>(obj)/array_size) % array_size; | ||
if(index2%2==0){ | ||
++index2; | ||
} | ||
if(index2 < 0){ | ||
index2 += array_size; | ||
} | ||
return index2; | ||
} | ||
|
||
template<typename T > | ||
bool DoubleHashTable<T >::member( T const &obj ) const { | ||
int probe = h1(obj); | ||
int offset = h2(obj); | ||
if ( !empty() ){ | ||
while (array_state[probe] == OCCUPIED && array[probe] != obj){ | ||
probe = (probe + offset)%array_size; | ||
} | ||
} | ||
return( array[probe] == obj); | ||
} | ||
|
||
template<typename T > | ||
T DoubleHashTable<T >::bin( int n ) const { | ||
if (array_state[n] = OCCUPIED) | ||
return array[n]; | ||
} | ||
|
||
template<typename T > | ||
void DoubleHashTable<T >::insert( T const &obj ) { | ||
int probe = h1(obj); | ||
int offset = h2(obj); | ||
if ( count == array_size ){ | ||
throw overflow(); | ||
} | ||
while (array_state[probe] == OCCUPIED){ | ||
probe = (probe + offset)%array_size; | ||
} | ||
array[probe] = obj; | ||
array_state[probe] = OCCUPIED; | ||
++count; | ||
} | ||
|
||
template<typename T > | ||
bool DoubleHashTable<T >::remove( T const &obj ) { | ||
int probe = h1(obj); | ||
int offset = h2(obj); | ||
if ( empty() ){ | ||
throw overflow(); | ||
} | ||
if (member(obj)){ | ||
while (array_state[probe] == OCCUPIED && array[probe] != obj){ | ||
probe = (probe + offset)%array_size; | ||
} | ||
array_state[probe] = DELETED; | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
template<typename T > | ||
void DoubleHashTable<T >::clear() { | ||
for (int i = 0; i < array_size; ++i){ | ||
//array[i] = 0; | ||
array_state[i] = EMPTY; | ||
} | ||
count = 0; | ||
} | ||
|
||
template<typename T > | ||
void DoubleHashTable<T >::print() const { | ||
for (int i = 0; i < array_size; ++i){ | ||
std::cout << "INDEX: " << i <<" "; | ||
std::cout << "KEY: " << array[i] <<" "; | ||
std::cout << "STATE: "<< array_state[i] << std::endl; | ||
} | ||
return; | ||
} | ||
|
||
#endif |
Oops, something went wrong.