1
0
Fork 0

Week 9: Assignment - Quicksort, Merge Sort

This commit is contained in:
Llewellyn van der Merwe 2020-11-01 23:10:02 +02:00
parent a5d84bfb7e
commit d1c5c73674
Signed by: Llewellyn
GPG Key ID: EFC0C720A240551C
6 changed files with 461 additions and 0 deletions

6
week-09-1/CMakeLists.txt Normal file
View File

@ -0,0 +1,6 @@
cmake_minimum_required(VERSION 3.16)
project(week-09-1)
set(CMAKE_CXX_STANDARD 14)
add_executable(week-09-1 main.cpp)

104
week-09-1/main.cpp Normal file
View File

@ -0,0 +1,104 @@
// Adaptation to the code found at
// Week 5: Lectures
// Demonstrates sorted linked list
#include <iostream>
using namespace std;
/////////////////////////////////////////////////////////////
class Node {
public:
int filenumber; // the file number
Node *pNext; // ptr to next link in list
//----------------------------------------------------------
Node(int value) : // constructor
filenumber(value), pNext(NULL) {}
//----------------------------------------------------------
void displayNode() // display ourselves {22}
{
cout << "{" << filenumber << "} ";
}
//----------------------------------------------------------
}; // end class Node
/////////////////////////////////////////////////////////////
class NodeList {
private:
Node *pFirst; // ptr to first link on list
public:
//----------------------------------------------------------
NodeList() : pFirst(NULL) // constructor
{} // no links on list yet
//----------------------------------------------------------
~NodeList(){ // destructor
while(!isEmpty()){ // until it's empty,
removeFirst(); // remove it
}
}
//----------------------------------------------------------
bool isEmpty() // true if list is empty
{ return pFirst == NULL; }
//----------------------------------------------------------
Node *getFirst() // return first link
{ return pFirst; }
//----------------------------------------------------------
void insert(int value) // insert, in order
{
Node* pNewLink = new Node(value); // make new link
Node* pPrevious = NULL; // pointer to previous
Node* pCurrent = pFirst; // start at first
// Look for position prior to the end of the list
// We quicksort insert by value
while(pCurrent != NULL && value > pCurrent->filenumber)
{
pPrevious = pCurrent; // adjust previous ptr
pCurrent = pCurrent->pNext; // go to next item
}
// Insert link the link
if(pPrevious==NULL) // at beginning of list
pFirst = pNewLink; // first --> newLink
else // not at beginning
pPrevious->pNext = pNewLink; // old prev --> newLink
pNewLink->pNext = pCurrent; // newLink --> old current
} // end insert()
//----------------------------------------------------------
void removeFirst() // delete first link
{ // (assumes list not empty)
Node *pTemp = pFirst; // save first
pFirst = pFirst->pNext; // unlink it: first-->old next
delete pTemp; // delete old first
}
//----------------------------------------------------------
void displayList() {
cout << "List (value): ";
Node *pCurrent = pFirst; // start at beginning of list
while (pCurrent != NULL) // until end of list,
{
pCurrent->displayNode(); // print data
pCurrent = pCurrent->pNext; // move to next link
}
cout << endl;
}
//----------------------------------------------------------
}; // end class NodeList
/////////////////////////////////////////////////////////////
int main() {
NodeList theList; // make new list
cout << "Demonstrating the sorted link-list program" << endl;
theList.insert(421003);
theList.insert(100298);
theList.insert(494002);
theList.insert(93);
theList.insert(3994);
theList.insert(21093);
theList.insert(3949500);
theList.insert(29100);
theList.insert(6493939);
theList.insert(202814);
theList.insert(506984);
theList.insert(2);
theList.insert(665778);
cout << " This is all the values that are now in the linked list" << endl;
theList.displayList();
return 0;
}

6
week-09-2/CMakeLists.txt Normal file
View File

@ -0,0 +1,6 @@
cmake_minimum_required(VERSION 3.16)
project(week-09-2)
set(CMAKE_CXX_STANDARD 14)
add_executable(week-09-2 main.cpp)

124
week-09-2/main.cpp Normal file
View File

@ -0,0 +1,124 @@
//SDEV345-81
//Kodi Lein
#include <iostream>
using namespace std;
/*Node Class*/
class Node
{
public:
int data;
Node* next;
Node* prev;
};
/*Swap elements*/
void swap(int* a, int* b)
{
int t = *a; *a = *b; *b = t;
}
/*Find last node in list*/
Node* lastNode(Node* root)
{
while (root && root->next)
root = root->next;
return root;
}
/*Define pivot point and moves smaller elements to left, larger to right*/
Node* partition(Node* l, Node* h)
{
//h = pivot point
int x = h->data;
Node* i = l->prev;
for (Node* j = l; j != h; j = j->next)
{
if (j->data <= x)
{
i = (i == NULL) ? l : i->next;
swap(&(i->data), &(j->data));
}
}
i = (i == NULL) ? l : i->next;
swap(&(i->data), &(h->data));
return i;
}
/*Quicksort function*/
void QS(Node* l, Node* h)
{
if (h != NULL && l != h && l != h->next)
{
Node* p = partition(l, h);
QS(l, p->prev);
QS(p->next, h);
}
}
//Calls function quicksort
void quickSort(Node* head)
{
// Find last node
Node* h = lastNode(head);
// Call the recursive QuickSort
QS(head, h);
}
void printList(Node* head)
{
while (head)
{
cout << head->data << " ";
head = head->next;
}
cout << endl;
}
/*Insert Node*/
void push(Node** head_ref, int new_data)
{
Node* new_node = new Node;
new_node->data = new_data;
new_node->prev = NULL;
new_node->next = (*head_ref);
if ((*head_ref) != NULL) (*head_ref)->prev = new_node;
(*head_ref) = new_node;
}
/*MAIN*/
int main()
{
Node* a = NULL;
push(&a, 421003);
push(&a, 100298);
push(&a, 494002);
push(&a, 93);
push(&a, 3394);
push(&a, 21093);
push(&a, 3949500);
push(&a, 29100);
push(&a, 6493939);
push(&a, 202814);
push(&a, 506984);
push(&a, 2);
push(&a, 665778);
cout << "Linked List before sorting \n";
printList(a);
quickSort(a);
cout << "\nLinked List after sorting \n";
printList(a);
return 0;
}

6
week-09-3/CMakeLists.txt Normal file
View File

@ -0,0 +1,6 @@
cmake_minimum_required(VERSION 3.16)
project(week-09-3)
set(CMAKE_CXX_STANDARD 14)
add_executable(week-09-3 main.cpp)

215
week-09-3/main.cpp Normal file
View File

@ -0,0 +1,215 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Champlain College SDEV-345-81
*
* C++ Week 9: Quicksort (first semester) - (2020/10/30)
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Write a program that will randomly populate an array of 250 integers and print them
* out in a formatted way to the console. Once printed, call a quicksort algorithm to
* sort the array and print it out again, this time in order.
*
* Include the worst case running time in your output.
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Written by Llewellyn van der Merwe <llewellyn.vandermerw@mymail.champlain.edu>, October 2020
* Copyright (C) 2020. All Rights Reserved
* License GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include <iostream>
#include <memory>
#include <chrono>
#include <ctime>
using namespace std;
using namespace std::chrono;
// Quick Sort Class
class QuickSort {
private:
// the comparison counter
int comparison_counter;
// local sort needed for quick sort
void sort(int *arr, int low, int high) {
// some default stuff
int i = low;
int j = high;
int pivot = *(arr + ((i + j) / 2));
int temp;
// compare the array positions
while (position_compare(&i, &j)) {
// compare the array values
while (compare(&pivot, (arr + i)))
i++;
// compare the array values
while (compare((arr + j), &pivot))
j--;
// compare the array positions
if (position_compare(&i, &j)) {
temp = *(arr + i);
*(arr + i) = *(arr + j);
*(arr + j) = temp;
i++;
j--;
}
}
// compare the array values
if (compare(&j, &low))
sort(arr, low, j);
// compare the array values
if (compare(&high, &i))
sort(arr, i, high);
}
// local compare for the positions
bool position_compare(int *a, int *b) {
comparison_counter++; // not sure if this should also be count (just comment out this line if not)
return *a <= *b;
}
// function to compare values
bool compare(int *a, int *b) {
comparison_counter++;
return *a > *b;
}
public:
// get comparison counter
int getComparisonCounter() { return comparison_counter; }
// sort function
void sort(int *arr, int size ) {
comparison_counter = 0;
sort(arr, 0, size - 1);
}
};
// function declarations
void printArray(int arr[], int size, string action);
void reverseArray(int arr[], int start, int end);
void printNotice(int microseconds, int comparisons, string status);
void printWorseCase(int random, int revers, int sorted);
// main function
int main() {
// the size of our array
const int SIZE = 250;
// for random seeding
time_t aTime;
// array we would like to sort
int arr[SIZE];
// Instantiate Quick Sort
shared_ptr<QuickSort> quick = make_shared<QuickSort>();
// Seed randoms
srand( static_cast<unsigned>(time(&aTime)) );
// load 250 random values (between 0 - 3000)
for(int i = 0; i < SIZE; i++) {
arr[i] = rand() % 3000;
}
// start the display
cout << endl << " | THE QUICKSORT DEMONSTRATION" << endl;
// display array before sorting
printArray(arr, SIZE, "Random");
// now we sort the the array
cout << " | Sorting the RANDOM array with Quicksort" << endl;
// get the starting point of the sort
auto start = high_resolution_clock::now();
// sort the array
quick->sort(arr, SIZE);
// After sort
auto stop = high_resolution_clock::now();
// display proof that the array was sorted
printArray(arr, SIZE, "Sorted");
// we get the duration of the sort in microseconds
auto duration = duration_cast<microseconds>(stop - start);
// give notice
printNotice(duration.count(), quick->getComparisonCounter(), "RANDOM");
// reverse the array to sort the array in worse case
reverseArray(arr, 0, SIZE-1);
// display proof that the array was reversed
printArray(arr, SIZE, "Reversed");
// now we sort the the array
cout << " | Sorting the REVERSED array with Quicksort" << endl;
// get the starting point of the sort
auto again_start = high_resolution_clock::now();
// sort the array
quick->sort(arr, SIZE);
// After sort
auto again_stop = high_resolution_clock::now();
// display proof that the was sorted
printArray(arr, SIZE, "Sorted");
// we get the duration of the sort in microseconds
auto again_duration = duration_cast<microseconds>(again_stop - again_start);
// give notice
printNotice(again_duration.count(), quick->getComparisonCounter(), "REVERSED");
// now we sort the the array
cout << "_|___________________________________________________" << endl;
cout << " | Sorting the SORTED array with Quicksort" << endl;
// get the starting point of the sort
auto and_again_start = high_resolution_clock::now();
// sort the array
quick->sort(arr, SIZE);
// After sort
auto and_again_stop = high_resolution_clock::now();
// proof that it was sorted
printArray(arr, SIZE, "Still Sorted");
// we get the duration of the sort in microseconds
auto and_again_duration = duration_cast<microseconds>(again_stop - again_start);
// give notice
printNotice(and_again_duration.count(), quick->getComparisonCounter(), "SORTED");
// print the worse case
printWorseCase(duration.count(), again_duration.count(), and_again_duration.count());
return 0;
}
// Function to reverse arr[] from start to end
// https://www.geeksforgeeks.org/write-a-program-to-reverse-an-array-or-string/
void reverseArray(int arr[], int start, int end)
{
while (start < end)
{
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
}
// Utility function to print an array
// https://www.geeksforgeeks.org/write-a-program-to-reverse-an-array-or-string/
void printArray(int arr[], int size, string action)
{
cout << "_|___________________________________________________" << endl;
cout << " | Display " << action;
for (int i = 0; i < size; i++) {
if (i % 20 == 0) {
cout << endl;
cout << " | ";
}
cout << arr[i] << " ";
}
cout << endl << "_|___________________________________________________" << endl;
}
// little function to print out notices
void printNotice(int microseconds, int comparisons, string status) {
// show the duration
cout << " | SORT Duration with (" << status << " ARRAY): " << microseconds << "μs" << endl;
// show the comparisons
cout << " | SORT Comparisons: " << comparisons << endl;
}
// little function to print the worse case
void printWorseCase(int random, int revers, int sorted) {
// show the worse case
cout << "_|___________________________________________________" << endl;
cout << " | QUICKSORT WORSE CASE WAS ";
if(random > revers && random > sorted) {
cout << "RANDOM ARRAY: " << random << "μs" << endl;
} else if(revers > random && revers > sorted) {
cout << "REVERSED ARRAY: " << revers << "μs" << endl;
} else {
cout << "SORTED ARRAY: " << sorted << "μs" << endl;
}
cout << "_|___________________________________________________" << endl;
}