summaryrefslogblamecommitdiff
path: root/Assign5/table.cpp
blob: 33a44de5a73a920bca526cc859f0f25e23efdb09 (plain) (tree)










































































































































































































































































                                                                                                                            
#include<iostream>
#include"table.hpp"

Table::Table(bool useChaining = false) {
	/* This constructor takes in a boolean value as a parameter. 
	The boolean value useChaining represents 
	whether or not the user intends on using separate chaining 
	as their hashing method. When set to true, the constructor 
	will create a table object represented by an array of pointers
	to the heads of linked lists, a structure more appropriate
	for separate chaining. When useChaining is false, the 
	constructor defaults to a simple array-based hash table.
	*/

	if (useChaining) {
	
		// initialize array of linked list heads
		for (int i = 0; i < 10; i++) {
			tableHeads[i] = NULL;
		}

	}
	else {
		unhashable = false;
		
		// initialize array with 'empty' values
		for (int i = 0; i < 10; i++) {
			tableArray[i] = EMPTY;
			unhashableList[i] = EMPTY;
		}
		
	}
	
}	

void Table::hashLinear(int intList[]) {
	/* Implementation of hash table insertion using linear probing.
	This method takes in an array of integers (10 items max) and hashes
	them into a table object using linear probing for conflict resolution.
	This means that the probe distance is equal to the number of probing 
	attempts, or, f(i) = i. An item cannot be hashed into the table if the probing 
	results in cycling around to the original insertion location again. 
	*/
	int count = 0;
	int slotIndex = 0;
	int originalSlotIndex;
	bool probeFinished;
	
	while (intList[count] != EMPTY && count < 10) {
		slotIndex = intList[count] % 10;
		
		if (tableArray[slotIndex] == EMPTY) { // slot empty; insert item
			tableArray[slotIndex] = intList[count];
		}
		else { // slot taken; must probe
			originalSlotIndex = slotIndex;
			probeFinished = false; 
			
			while (!probeFinished) {
				slotIndex++; // f(i) = i
				
				if (slotIndex > 9) { // wrap around array
					slotIndex = slotIndex - 10;
				}
				
				if (slotIndex == originalSlotIndex) { // gone over whole array; end probing
					unhashable = true;
					unhashableList[count] = intList[count];
					probeFinished = true;
				}
				
				if (tableArray[slotIndex] == EMPTY) { // slot empty; insert item
					tableArray[slotIndex] = intList[count];
					probeFinished = true;
				}
								
			}
			
		}
			
		count++;
	}
	
}

void Table::hashQuad(int intList[]) {
	/* Implementation of hash table insertion using quadratic probing.
	This method takes in an array of integers (10 items max) and hashes
	them into a table object using quadratic probing for conflict resolution.
	This means that the probe distance is equal to the number of probing
	attempts squared, or, f(i) = i^2. An item cannot be hashed into the table if the probing 
	results in cycling around to the original insertion location again. 
	*/
	int count = 0;
	int probeCount = 0;
	int slotIndex = 0;
	int originalSlotIndex;
	bool probeFinished;
	
	while (intList[count] != EMPTY && count < 10) {
		slotIndex = intList[count] % 10;
		
		if (tableArray[slotIndex] == EMPTY) { // slot empty; insert item
			tableArray[slotIndex] = intList[count];
		}
		else { // slot taken; must probe
			originalSlotIndex = slotIndex;
			probeCount = 0;
			probeFinished = false; 
			
			while (!probeFinished) { 
				probeCount++;
				slotIndex = originalSlotIndex + (probeCount * probeCount); // f(i) = i^2
				
				while (slotIndex > 9) { // wrap around array multiple times
					slotIndex = slotIndex - 10;
				}
				
				if (probeCount > 5) { 
					unhashable = true;
					unhashableList[count] = intList[count];
					probeFinished = true;
				}
				
				if (tableArray[slotIndex] == EMPTY) { // slot empty; insert item
					tableArray[slotIndex] = intList[count];
					probeFinished = true;
				}
								
			}
			
		}
			
		count++;
	}
	
}

void Table::hashDouble(int intList[]) {
	/* Implementation of hash table insertion using double hashing. 
	This method takes in an array of integers (10 items max) and hashes
	them into a table object using a second hash function for conflict resolution. 
	The second hash function is equivalent to f(x) = 7 - x % 7. An item cannot be 
	hashed into the table if the probing results in cycling around to the original 
	insertion location again. 
	*/
	int count = 0;
	int probeCount = 0;
	int slotIndex = 0;
	int originalSlotIndex;
	bool probeFinished;
	
	while (intList[count] != EMPTY && count < 10) {
		slotIndex = intList[count] % 10;
		
		if (tableArray[slotIndex] == EMPTY) { // slot empty; insert item
			tableArray[slotIndex] = intList[count];
		}
		else { // slot taken; must probe
			originalSlotIndex = slotIndex;
			probeCount = 0;
			probeFinished = false; 
			
			while (!probeFinished) {
				probeCount++;
				slotIndex = originalSlotIndex + (probeCount * (7 - intList[count] % 7)); // f(x) = 7 - x % 7
				
				while (slotIndex > 9) { // wrap around array 
					slotIndex = slotIndex - 10;
				}
				
				if (slotIndex == originalSlotIndex) { // gone over whole array; end probing
					unhashable = true;
					unhashableList[count] = intList[count];
					probeFinished = true;
				}
				
				if (tableArray[slotIndex] == EMPTY) { // slot empty; insert item
					tableArray[slotIndex] = intList[count];
					probeFinished = true;
				}
								
			}
			
		}
			
		count++;
	}
	
}

void Table::hashChaining(int intList[]) {
	/* Implementation of hash table insertion using separate chaining. 
	This method takes in an array of integers (10 items max) and hashes 
	the items into a table object using separate chaining for conflict
	resolution. This means for each insertion index, a linked list exists
	where all of the values that hash to that index are inserted at the head
	of the linked list.
	*/
	int count = 0;
	int slotIndex = 0;
	NODE *newHead;
	
	while (intList[count] != EMPTY && count < 10) {
		newHead = new NODE();
		slotIndex = intList[count] % 10;
		newHead->key = intList[count];
		newHead->next = tableHeads[slotIndex];
		tableHeads[slotIndex] = newHead;
		count++;
	}

}

void Table::printTable(bool useChaining = false) {
	/* A method for printing out the contents of a hash table object
	that creates a visual representation of the hash table and its
	contents and prints them to the console (or a file if directed).
	This method takes in a boolean value letting the method know 
	whether or not to print a separately-chained linked hash table
	with a linke list or a hash table based on an array (ex. linear 
	probing).
	*/
	if (useChaining) {
		NODE *node = new NODE();
		
		// print visual hash table of items from linked lists
		for (int i = 0; i < 10; i++) {
			std::cout << "[" << i << "]" << "-> ";
			
			for (node = tableHeads[i]; node != NULL; node = node->next) {
				std::cout << node->key << " -> ";
				delete node; // have to clean up nodes from memory
			}
			
			std::cout << "_\n";
		}
		
	}	
	else {
		// print visual hash table of items from array
		for (int i = 0; i < 10; i++) {
			std::cout << "[" << i << "]" << "   ";
	
			if (tableArray[i] != EMPTY) {
				std::cout << tableArray[i];
			}
		
			std::cout << "\n";
		}
	
		// print items that could not be inserted
		if (unhashable) {
			std::cout << "The following item(s) could not be inserted:  ";
	
			for (int i = 0; i < 10; i++) {
			
				if (unhashableList[i] != EMPTY) {
					std::cout << unhashableList[i] << " ";
				}
						
			}
		
			std::cout << "\n";
		}
	}
}