PROGRAM 6
// FILENAME: PROGRAM6.CPP AUTHOR: ANTHONY F. ORTIZ // HEADER FILES. #include #include #include #include #include #include // OUTFILE ofstream OUTFILE; // DECLARATION OF HASH TABLE WITH QUADRATIC OR LINEAR PROBING. // DEFAULT SIZE OF HASH TABLE. SHOULD BE TWICE AS LARGE AS THE NUMBER // OF PLANNED INSERTIONS. ALSO, IT SHOULD BE PRIME. (THIS WILL HAPPEN // LATER ON. const int DEFAULT_SIZE = 200; template class HASH_TABLE { public: // KIND OF ENTRY. enum KIND_OF_ENTRY {LEGITIMATE, EMPTY, DELETED}; protected: // HASH ENTRY. struct HASH_ENTRY { ELEMENT_TYPE ELEMENT; KIND_OF_ENTRY INFO; HASH_ENTRY (ELEMENT_TYPE E = -1, KIND_OF_ENTRY I = EMPTY) : ELEMENT (E), INFO (I) {} }; // THE SIZE OF HASH TABLE. SHOULD BE TWICE AS LARGE AND // PRIME. unsigned int H_SIZE; // THE CELLS OF THE HASH TABLE. HASH_ENTRY * THE_CELLS; // LAST CELL ACCESSED. unsigned int CURRENT_CELL; // ALLOCATE CELLS FROM THE HEAP. void ALLOCATE_CELLS (); // DISABLED. HASH_TABLE (HASH_TABLE & VALUE); // NUMBER OF COLLISIONS. int COLLISIONS; public: // CONSTRUCTORS. HASH_TABLE (unsigned int INITIAL_SIZE = DEFAULT_SIZE); // DESTRUCTOR. virtual ~HASH_TABLE () {delete [] THE_CELLS;} // OPERATORS. // COPY A HASH TABLE USING THE '=' OPERATOR. const HASH_TABLE & operator = (const HASH_TABLE & VALUE); // GET AN INDIVIDUAL HASH TABLE CELL. ELEMENT_TYPE operator () () const {return THE_CELLS [CURRENT_CELL].ELEMENT;} // MEMBER FUNCTIONS. virtual void INITIALIZE_TABLE (); // INSERT INTO HASH TABLE USING EITHER QUADRATIC OR // LINEAR PROBING. virtual void INSERT (const ELEMENT_TYPE & KEY); // REMOVE FROM THE HASH TABLE USING EITHER QUADRATIC OR // LINEAR PROBING. void REMOVE (const ELEMENT_TYPE & KEY); // FIND A OPEN HASH CELL USING QUADRATIC PROBING. int FIND (const ELEMENT_TYPE & KEY); // FIND A OPEN HASH CELL USING LINEAR PROBING. int FIND2 (const ELEMENT_TYPE & KEY); // HASH FUNCTION. int HASH (const int KEY, const int H_SIZE); // PRINT THE HASH TABLE. void PRINT_TABLE (); // PRINT THE NUMBER OF COLLISIONS. void PRINT_COLLISIONS (); }; // ALLOCATE CELLS FROM THE HEAP. template void HASH_TABLE :: ALLOCATE_CELLS () { THE_CELLS = new HASH_ENTRY [H_SIZE]; if (THE_CELLS == 0) cout << "OUT OF SPACE!!"; } // INITIALIZE COLLISIONS AND HASH SIZE. template HASH_TABLE :: HASH_TABLE (unsigned int INITIAL_SIZE) { // FLAG TO TELL WHETHER NUMBER IS PRIME. int FLAG; COLLISIONS = 0; // FIND A PRIME NUMBER GREATER THAN TWICE THE NUMBER OF INSERTIONS. do { FLAG = 1; for (int I = 2; I < INITIAL_SIZE; I++) { if (INITIAL_SIZE % I == 0) { FLAG = 0; break; } } if (FLAG == 0) { INITIAL_SIZE++; } } while (FLAG == 0); H_SIZE = INITIAL_SIZE; ALLOCATE_CELLS (); } // INITIALIZE HASH TABLE. template void HASH_TABLE :: INITIALIZE_TABLE () { delete [] THE_CELLS; ALLOCATE_CELLS (); } // COPY HASH TABLE USING '=' OPERATOR. template const HASH_TABLE & HASH_TABLE :: operator = (const HASH_TABLE & VALUE) { if (this != &VALUE) { delete [] THE_CELLS; H_SIZE = VALUE.H_SIZE; ALLOCATE_CELLS (); for (int I = 0; I < H_SIZE; I++) THE_CELLS [I] = VALUE.THE_CELLS [I]; } return *this; } // FIND OPEN HASH TABLE CELL USING QUADRATIC PROBING. template int HASH_TABLE :: FIND (const ELEMENT_TYPE & KEY) { unsigned int I = 0; CURRENT_CELL = HASH (KEY, H_SIZE); while (THE_CELLS [CURRENT_CELL].INFO != EMPTY && THE_CELLS [CURRENT_CELL].ELEMENT != KEY) { COLLISIONS++; CURRENT_CELL += 2 * (++I) - 1; if (CURRENT_CELL >= H_SIZE) CURRENT_CELL -= H_SIZE; } return THE_CELLS [CURRENT_CELL].INFO == LEGITIMATE && THE_CELLS [CURRENT_CELL].ELEMENT == KEY; } // FIND OPEN HASH TABLE CELL USING LINEAR PROBING. template int HASH_TABLE :: FIND2 (const ELEMENT_TYPE & KEY) { unsigned int I = 0; CURRENT_CELL = HASH (KEY, H_SIZE); while (THE_CELLS [CURRENT_CELL].INFO != EMPTY && THE_CELLS [CURRENT_CELL].ELEMENT != KEY) { COLLISIONS++; CURRENT_CELL += ++I; if (CURRENT_CELL >= H_SIZE) CURRENT_CELL -= H_SIZE; } return THE_CELLS [CURRENT_CELL].INFO == LEGITIMATE && THE_CELLS [CURRENT_CELL].ELEMENT == KEY; } // INSERT INTO THE HASH TABLE USING EITHER QUADRARIC OR LINEAR PROBING. template inline void HASH_TABLE :: INSERT (const ELEMENT_TYPE & KEY) { if (FIND (KEY) == 0) THE_CELLS [CURRENT_CELL] = HASH_ENTRY (KEY, LEGITIMATE); } // REMOVE FROM THE HASH TABLE USING EITHER QUADRATIC OR LINEAR PROBING. template inline void HASH_TABLE :: REMOVE (const ELEMENT_TYPE & KEY) { if (FIND (KEY)) THE_CELLS [CURRENT_CELL] = HASH_ENTRY (-1, DELETED); else cout << "ITEMS NOT FOUND"; } // PRINT THE HASH TABLE. template void HASH_TABLE :: PRINT_TABLE () { for (int I = 0; I < H_SIZE; I++) { OUTFILE << setw (8) << THE_CELLS [I].ELEMENT; if ((I + 1) % 10 == 0) { OUTFILE << "\n"; } } } // PRINT THE NUMBER OF COLLISIONS IN THE HASH TABLE. template void HASH_TABLE :: PRINT_COLLISIONS () { OUTFILE << "\nTHERE WERE " << COLLISIONS << " COLLISIONS.\n"; } // HASH FUNCTION. template int HASH_TABLE :: HASH (const int KEY, const int H_SIZE) { return KEY % H_SIZE; } // INSERT 100 INTEGERS INTO A HASH TABLE AND DELETE 20 OF THEM FROM THE // HASH TABLE USING EITHER (QUADRTIC OR LINEAR PROBING). ALSO, PRINT THE // HASH TABLE AND THE NUMBER OF COLLISIONS. int main () { // OPEN OUT FILE. OUTFILE.open ("HASH.OUT", ios :: out); // CLEAR SCREEN. clrscr (); // MAKE EACH EXECUTION DIFFERENT. randomize (); // DECLARE VARIABLE FOR HASH TABLE. HASH_TABLE A_INT_TABLE; // HOLDS THE CURRENT RANDOM NUMBER. int RANDOM_NUMBER; // HOLDS THE CURRENT RANDOM NUMBER. NEEDED FOR REMOVAL. int TEMP; // HOLDS THE 100 RANDOM INTEGERS. // THIS WILL BE USED FOR DELETION. int RANDOM_ARRAY [100]; // INSERT 100 RANDOM INTEGERS FROM 0 TO 9999 INTO THE HASH TABLE. for (int I = 0; I <= 99; I++) { // GET RANDOM NUMBER. RANDOM_NUMBER = rand () % 10000; // INSERT IT INTO THE HASH TABLE. A_INT_TABLE.INSERT (RANDOM_NUMBER); // ALSO, INSERT IT INTO AN ARRAY. RANDOM_ARRAY [I] = RANDOM_NUMBER; } // PRINT A HEADING AND THEN THE HASH TABLE. OUTFILE << "AFTER 100 INSERTIONS:\n"; A_INT_TABLE.PRINT_TABLE (); A_INT_TABLE.PRINT_COLLISIONS (); // REMOVE 20 ELEMENTS FROM THE HASH TABLE. for (int J = 0; J <= 19; J++) { // LOOP IF THE RANDOM NUMBER IS NOT IN THE ARRAY. // THIS MIGHT HAPPEN IF IT HAS BEEN REMOVED FROM // TABLE AND THE ARRAY. do { // RANDOM NUMBER FROM 0 TO 99. // INDEX OF THE ARRAY. RANDOM_NUMBER = (rand () % 100); } while (RANDOM_ARRAY [RANDOM_NUMBER] == 0); // HOLD THE RANDOM NUMBER. TEMP = RANDOM_ARRAY [RANDOM_NUMBER]; // PUT 0 IN THE ARRAY OF THE APPROPRIATE INDEX. RANDOM_ARRAY [RANDOM_NUMBER] = 0; // PUT THE RANDOM NUMBER IN THE TEMP VARIABLE INTO // THE RANDOM NUMBER VARIABLE. RANDOM_NUMBER = TEMP; // REMOVE THE RANDOM NUMBER. A_INT_TABLE.REMOVE (RANDOM_NUMBER); } OUTFILE << "\nAFTER 20 DELETIONS:\n"; A_INT_TABLE.PRINT_TABLE (); // CLOSE OUTFILE. OUTFILE.close (); return 0; } // OUTFILE: HASH.OUT AFTER 100 INSERTIONS: 2532 -1 9075 -1 1903 -1 1905 9924 2117 9503 2960 -1 -1 8871 -1 5501 4868 -1 -1 441 -1 5929 -1 -1 -1 -1 -1 4880 -1 -1 -1 -1 7839 6152 1722 1300 -1 4890 -1 -1 -1 -1 5317 6795 -1 -1 -1 -1 -1 -1 -1 8491 9547 -1 -1 -1 -1 -1 9764 481 -1 6391 484 -1 5339 694 5341 -1 1967 -1 7033 -1 1549 7660 3239 1973 -1 6618 285 -1 1135 8309 8733 1138 -1 -1 272 -1 -1 -1 8108 9797 725 4945 9589 3259 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1584 -1 2219 7494 -1 7497 4122 -1 -1 -1 2860 -1 963 -1 6451 7084 -1 -1 -1 -1 2237 7724 4770 -1 4140 2031 -1 -1 2245 4145 6678 -1 983 3726 7948 -1 -1 5204 -1 -1 6883 -1 360 -1 -1 -1 -1 -1 5430 5642 9019 -1 -1 582 -1 8813 -1 3118 7339 588 -1 3755 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 180 -1 -1 6724 -1 -1 8415 -1 5885 4620 -1 -1 4197 4412 5047 -1 -1 830 8638 8216 -1 1252 3996 4001 -1 -1 619 -1 2107 6312 -1 THERE WERE 49 COLLISIONS. AFTER 20 DELETIONS: 2532 -1 9075 -1 1903 -1 1905 -1 2117 9503 2960 -1 -1 8871 -1 5501 -1 -1 -1 441 -1 5929 -1 -1 -1 -1 -1 4880 -1 -1 -1 -1 7839 6152 1722 1300 -1 4890 -1 -1 -1 -1 5317 6795 -1 -1 -1 -1 -1 -1 -1 8491 9547 -1 -1 -1 -1 -1 9764 481 -1 -1 484 -1 5339 694 5341 -1 -1 -1 7033 -1 1549 7660 -1 -1 -1 6618 285 -1 1135 8309 -1 1138 -1 -1 272 -1 -1 -1 8108 -1 725 4945 -1 3259 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1584 -1 2219 -1 -1 7497 -1 -1 -1 -1 2860 -1 -1 -1 6451 -1 -1 -1 -1 -1 2237 -1 4770 -1 -1 2031 -1 -1 2245 4145 6678 -1 983 -1 7948 -1 -1 5204 -1 -1 6883 -1 360 -1 -1 -1 -1 -1 5430 -1 -1 -1 -1 582 -1 8813 -1 3118 7339 588 -1 3755 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 180 -1 -1 6724 -1 -1 8415 -1 5885 4620 -1 -1 4197 4412 5047 -1 -1 830 8638 8216 -1 1252 3996 4001 -1 -1 619 -1 -1 -1 -1
BACK TO CS3240 PAGE.