PROGRAM 5
// FILE_NAME: PROGRAM5.CPP (SORTING) AUTHOR: ANTHONY F. ORTIZ // HEADER FILES. #include #include #include #include #include // OUTFILE. ofstream FILEOUT; // DECLARATION FOR A CLASS CALLED SORTING. INCLUDES INSERTION, SHELL // HEAP, MERGE, AND QUICK SORT ROUTINES. template class SORTING { public: // INPUT THE ARRAY. INPUT_ARRAY (ETYPE INTEGER_ARRAY [], int SIZE); // INSERTION SORT. INSERTION_SORT (ETYPE INTEGER_ARRAY [], int SIZE); // FIND MINIMUM VALUE OF AN ARRAY. USED FOR INSERTION // SORT. MIN_VALUE (ETYPE INTEGER_ARRAY [], int SIZE); // SHELL SORT. SHELL_SORT (ETYPE INTEGER_ARRAY [], int SIZE); // HEAP SORT. HEAP_SORT (ETYPE HEAP_ARRAY [], ETYPE INTEGER_ARRAY [], int SIZE); // DELETE THE MINIMUM VALUE IN THE HEAP. USED FOR // HEAP SORT. ETYPE DELETE_MIN (ETYPE HEAP_ARRAY [], int & SIZE2); // BUILD THE HEAP. USED FOR HEAP SORT. INSERT (ETYPE HEAP_ARRAY [], ETYPE X, int & SIZE2); // MERGE SORT. MERGE_SORT (ETYPE INTEGER_ARRAY [], int SIZE); // USED WITH MERGE SORT. M_SORT (ETYPE INTEGER_ARRAY [], ETYPE TMP_ARRAY [], int LEFT, int RIGHT); // USED WITH MERGE SORT. MERGE (ETYPE INTEGER_ARRAY [], ETYPE TMP_ARRAY [], int LEFT_POS, int RIGHT_POS, int RIGHT_END); // QUICK SORT. QUICK_SORT (ETYPE A [], int N); // USED WITH QUICK SORT. ETYPE & MEDIAN3 (ETYPE INTEGER_ARRAY [], int LEFT, int RIGHT); // USED WITH QUICK SORT. Q_SORT (ETYPE INTEGER_ARRAY [], int LEFT, int RIGHT); // SWAP TWO ELEMENTS. USED WITH SEVERAL SORTING ROUTINES. SWAP (ETYPE A, ETYPE B); // PRINT THE ARRAY. PRINT_ARRAY (ETYPE INTEGER_ARRAY [], int SIZE); }; // IMPLEMENTATION FOR A CLASS CALLED SORTING. // INPUT AN ARRAY OF INTEGERS FROM 0 TO 9999 USING THE RANDOM FUNCTION. template SORTING :: INPUT_ARRAY (ETYPE INTEGER_ARRAY [], int SIZE) { randomize (); for (int I = 0; I < SIZE; I++) { INTEGER_ARRAY [I] = rand () % 10000; } return 0; } // INSERTION SORT. template SORTING :: INSERTION_SORT (ETYPE INTEGER_ARRAY [], int SIZE) { ETYPE TEMP; MIN_VALUE (INTEGER_ARRAY, SIZE); for (int P = 2; P <= SIZE; P++) { TEMP = INTEGER_ARRAY [P]; for (int J = P; TEMP < INTEGER_ARRAY [J - 1]; J--) { INTEGER_ARRAY [J] = INTEGER_ARRAY [J - 1]; } INTEGER_ARRAY [J] = TEMP; } return 0; } // FIND THE MINIMUM VALUE OF THE ARRAY AND SWAP IT WILL THE FIRST ELEMENT // OF THE ARRAY. USED WITH INSERTION SORT. template SORTING :: MIN_VALUE (ETYPE INTEGER_ARRAY [], int SIZE) { ETYPE SMALLEST = INTEGER_ARRAY [0]; int INDEX = 0; ETYPE TEMP; for (int I = 0; I <= SIZE; I++) { if (INTEGER_ARRAY [I] <= SMALLEST) { SMALLEST = INTEGER_ARRAY [I]; INDEX = I; } } TEMP = INTEGER_ARRAY [0]; INTEGER_ARRAY [0] = SMALLEST; INTEGER_ARRAY [INDEX] = TEMP; return 0; } // SHELL SORT. template SORTING :: SHELL_SORT (ETYPE INTEGER_ARRAY [], int SIZE) { ETYPE TEMP; for (int INCREMENT = SIZE / 2; INCREMENT > 0; INCREMENT /= 2) { // NOT INCREMENT + 1, INCREMENT. for (int I = INCREMENT; I <= SIZE; I++) { TEMP = INTEGER_ARRAY [I]; // NOT J > INCREMENT, J >= INCREMENT. for (int J = I; J >= INCREMENT; J -= INCREMENT) { if (TEMP < INTEGER_ARRAY [J - INCREMENT]) { INTEGER_ARRAY [J] = INTEGER_ARRAY [J - INCREMENT]; } else { break; } } INTEGER_ARRAY [J] = TEMP; } } return 0; } // HEAP SORT ROUTINE. template SORTING :: HEAP_SORT (ETYPE HEAP_ARRAY [], ETYPE INTEGER_ARRAY [], int SIZE) { HEAP_ARRAY [0] = -1; int SIZE2 = 0; for (int I = 1; I < SIZE; I++) // BUILD HEAP. { INSERT (HEAP_ARRAY, HEAP_ARRAY [I], SIZE2); } for (I = 1; I < SIZE ; I++) // GET MINIMUM VALUE OF HEAP. { INTEGER_ARRAY [I] = DELETE_MIN (HEAP_ARRAY, SIZE2); } return 0; } // BUILD THE HEAP. USED WITH HEAP SORT. template SORTING :: INSERT (ETYPE HEAP_ARRAY [], ETYPE X, int & SIZE2) { unsigned int I; I = ++SIZE2; while (HEAP_ARRAY [I / 2] > X) { HEAP_ARRAY [I] = HEAP_ARRAY [I / 2]; I /= 2; } HEAP_ARRAY [I] = X; return 0; } // DELETE THE MINIMUM VALUE FROM THE HEAP. USED WITH HEAP SORT. template ETYPE SORTING :: DELETE_MIN (ETYPE HEAP_ARRAY [], int &SIZE2) { unsigned int CHILD; ETYPE MIN_ELEMENT, LAST_ELEMENT; MIN_ELEMENT = HEAP_ARRAY [1]; LAST_ELEMENT = HEAP_ARRAY [SIZE2--]; for (int I = 1; I * 2 <= SIZE2; I = CHILD) { // FIND SMALLER CHILD. CHILD = I * 2; if (CHILD != SIZE2) if (HEAP_ARRAY [CHILD + 1] < HEAP_ARRAY [CHILD]) CHILD++; // PERCOLATE ONE LEVEL. if (LAST_ELEMENT > HEAP_ARRAY [CHILD]) HEAP_ARRAY [I] = HEAP_ARRAY [CHILD]; else break; } HEAP_ARRAY [I] = LAST_ELEMENT; return MIN_ELEMENT; } // MERGE SORT. template SORTING :: MERGE_SORT (ETYPE INTEGER_ARRAY [], int SIZE) { ETYPE * TMP_ARRAY = new ETYPE [SIZE]; unsigned int NEW_N = SIZE; // NON-CONSTANT, FOR M-SORT. if (TMP_ARRAY != 0) { // NOT 1, 0. M_SORT (INTEGER_ARRAY, TMP_ARRAY, 0, NEW_N); delete [] TMP_ARRAY; } else { cout << "ERROR, NO SPACE FOR TMP ARRAY."; } return 0; } // USED BY MERGE SORT ROUTINE. template SORTING :: M_SORT (ETYPE INTEGER_ARRAY [], ETYPE TMP_ARRAY [], int LEFT, int RIGHT) { if (LEFT < RIGHT) { int CENTER = (LEFT + RIGHT) / 2; M_SORT (INTEGER_ARRAY, TMP_ARRAY, LEFT, CENTER); M_SORT (INTEGER_ARRAY, TMP_ARRAY, CENTER + 1, RIGHT); MERGE (INTEGER_ARRAY, TMP_ARRAY, LEFT, CENTER + 1, RIGHT); } return 0; } // USED BY MERGE SORT ROUTINE. // LEFT_POS = START OF LEFT HALF. // RIGHT_POS = START OF RIGHT HALF. template SORTING :: MERGE (ETYPE INTEGER_ARRAY [], ETYPE TMP_ARRAY [], int LEFT_POS, int RIGHT_POS, int RIGHT_END) { int LEFT_END = RIGHT_POS - 1; int TMP_POS = LEFT_POS; int NUM_ELEMENTS = RIGHT_END - LEFT_POS + 1; // MAIN LOOP. while (LEFT_POS <= LEFT_END && RIGHT_POS <= RIGHT_END) { if (INTEGER_ARRAY [LEFT_POS] <= INTEGER_ARRAY [RIGHT_POS]) { TMP_ARRAY [TMP_POS++] = INTEGER_ARRAY [LEFT_POS++]; } else { TMP_ARRAY [TMP_POS++] = INTEGER_ARRAY [RIGHT_POS++]; } } while (LEFT_POS <= LEFT_END) // COPY REST OF FIRST HALF. { TMP_ARRAY [TMP_POS++] = INTEGER_ARRAY [LEFT_POS++]; } while (RIGHT_POS <= RIGHT_END) // COPY REST OF SECOND HALF. { TMP_ARRAY [TMP_POS++] = INTEGER_ARRAY [RIGHT_POS++]; } // COPY TMP_ARRAY BACK. for (int I = 1; I <= NUM_ELEMENTS; I++, RIGHT_END--) { INTEGER_ARRAY [RIGHT_END] = TMP_ARRAY [RIGHT_END]; } \ return 0; } // QUICK SORT. template SORTING :: QUICK_SORT (ETYPE INTEGER_ARRAY [], int SIZE) { // NOT 1, 0. int ONE = 0; Q_SORT (INTEGER_ARRAY, ONE, SIZE); INSERTION_SORT (INTEGER_ARRAY, SIZE); return 0; } // USED BY QUICK SORT ROUTINE. template ETYPE & SORTING :: MEDIAN3 (ETYPE INTEGER_ARRAY [], int LEFT, int RIGHT) { int CENTER = (LEFT + RIGHT) / 2; if (INTEGER_ARRAY [LEFT] > INTEGER_ARRAY [CENTER]) { SWAP (INTEGER_ARRAY [LEFT], INTEGER_ARRAY [CENTER]); } if (INTEGER_ARRAY [LEFT] > INTEGER_ARRAY [RIGHT]) { SWAP (INTEGER_ARRAY [LEFT], INTEGER_ARRAY [RIGHT]); } if (INTEGER_ARRAY [CENTER] > INTEGER_ARRAY [RIGHT]) { SWAP (INTEGER_ARRAY [CENTER], INTEGER_ARRAY [RIGHT]); } // INVARIANT: A [LEFT] <= A [CENTER] <= A [RIGHT] // NOW HIDE AND RETURN PIVOT. SWAP (INTEGER_ARRAY [CENTER], INTEGER_ARRAY [RIGHT - 1]); return INTEGER_ARRAY [RIGHT - 1]; } // USED BY QUICK SORT ROUTINE. template SORTING :: Q_SORT (ETYPE INTEGER_ARRAY [], int LEFT, int RIGHT) { // CUTOFF NOT DECLARED, SHOULD BE DECLARED. // CUTOFF NOT INITIALIZED, SHOULD BE INITIALIZED. // BOOK RECOMMENDS 20 FOR CUTOFF. int CUTOFF = 20; if (LEFT + CUTOFF <= RIGHT) { ETYPE PIVOT = MEDIAN3 (INTEGER_ARRAY, LEFT, RIGHT); int I = LEFT; int J = RIGHT - 1; for ( ;;) { while (INTEGER_ARRAY [++I] < PIVOT); while (INTEGER_ARRAY [--J] > PIVOT); if (I < J) { SWAP (INTEGER_ARRAY [I], INTEGER_ARRAY [J]); } else { break; } } SWAP (INTEGER_ARRAY [I], INTEGER_ARRAY [RIGHT - 1]); // RESTORE PIVOT. Q_SORT (INTEGER_ARRAY, LEFT, I - 1); Q_SORT (INTEGER_ARRAY, I + 1, RIGHT); } return 0; } // USED BY QUICK SORT ROUTINE. template SORTING :: SWAP (ETYPE A, ETYPE B) { ETYPE TEMP = A; A = B; B = TEMP; return 0; } // PRINT THE UNSORTED OR SORTED ARRAY. template SORTING :: PRINT_ARRAY (ETYPE INTEGER_ARRAY [], int SIZE) { int COUNT = 0; for (int I = 0; I < SIZE; I++) { FILEOUT << setw (8) << INTEGER_ARRAY [I]; COUNT = COUNT + 1; if (COUNT % 10 == 0) { FILEOUT << "\n"; } } return 0; } // INPUT 5 NUMBERS, SORT THEM USING INSERTION SORT, AND PRINT THEM. int main () { SORTING SORT; int INT_ARRAY [5]; int SIZE = 5; FILEOUT.open ("SORT.OUT", ios :: out); SORT.INPUT_ARRAY (INT_ARRAY, SIZE); FILEOUT << "BEFORE SORT\n"; SORT.PRINT_ARRAY (INT_ARRAY, SIZE); SORT.INSERTION_SORT (INT_ARRAY, SIZE); FILEOUT << "\nAFTER SORT\n"; SORT.PRINT_ARRAY (INT_ARRAY, SIZE); FILEOUT.close (); return 0; } // OUTFILE: SORT.OUT BEFORE SORT 6599 6245 7964 1232 4156 AFTER SORT 170 1232 4156 6245 6599
BACK TO CS3240 PAGE.