//myHelper/DynamicInt64Array.h //Matthew Ellison // Created: 03-08-19 //Modified: 03-10-19 //This is the implementation for a dynamic array in c /* Copyright (C) 2019 Matthew Ellison This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #ifndef DYNAMIC_ARRAY_H #define DYNAMIC_ARRAY_H #include #include #include struct DynamicInt64Array{ int64_t* ptr; //The pointer to the array uint64_t size; //How many values are stored in the array uint64_t allocated; //How many values can be stored in the current array }; //This function initializes the array by allocating an array of size 2 and making sure the size trackers have accurate data void initDynamicInt64Array(struct DynamicInt64Array* ary){ //If NULL was sent to the function do nothing if(ary == NULL){ return; } ary->ptr = (int64_t*)malloc(2*sizeof(int64_t)); ary->allocated = 2; ary->size = 0; } //This function frees all of the dynamically allocated memory used in the array. Should be called after array is finished being used void destroyDynamicInt64Array(struct DynamicInt64Array* ary){ //If the array passed into the function is NULL do nothing if(ary == NULL){ return; } //If memory has been allocated for the array, release it if(ary->ptr != NULL){ free(ary->ptr); } ary->ptr = NULL; ary->size = 0; ary->allocated = 0; } //This function makes sure there is at least a certain number of elements available in this array void reserveDynamicInt64Array(struct DynamicInt64Array* ary, uint64_t size){ //If the array passed into the function is NULL do nothing if(ary == NULL){ return; } //If you are trying to reserve less than what is already available, do nothing if(size < ary->allocated){ return; } //Create a new array with the propper size int64_t* newAry = (int64_t*)malloc(size * sizeof(int64_t)); //Adjust the value of the amount of memory that has been saved for the array ary->allocated = size; //Copy all elements from the old array to the new one for(uint64_t cnt = 0;cnt < ary->size;++cnt){ newAry[cnt] = ary->ptr[cnt]; } //Free the space held by the old array if(ary->ptr != NULL){ free(ary->ptr); } //Assign the new array to the old array ary->ptr = newAry; } //This function adds an element to the array, expanding the size if necessary void pushBackDynamicInt64Array(struct DynamicInt64Array* ary, int64_t num){ //If NULL was passed into the fuction as a pointer do nothing if(ary == NULL){ return; } //If there is not enough room for the new element double the possible size of the array if(ary->allocated == ary->size){ reserveDynamicInt64Array(ary, ary->size * 2); //Double the size of the array } //Add the new element to the array ary->ptr[ary->size] = num; ++ary->size; } //This function takes the last element off of the array and returns that element int64_t popBackDynamicInt64Array(struct DynamicInt64Array* ary){ //If NULL was passed in as a pointer do nothing if(ary == NULL){ return 0; } //If there is an element that can be popped off remove it and return it if(ary->size > 0){ --ary->size; return ary->ptr[ary->size]; } //Otherwise do nothing else{ return 0; } } //This function removes the first element in the array that matches num void removeDynamicInt64Array(struct DynamicInt64Array* ary, int64_t num){ //If NULL was passed to the function as an array do nothing if(ary == NULL){ return; } //Look at every element in the array, trying to find one that is the same as num uint64_t location = 0; for(location = 0;location < ary->size;++location){ //If you find an elemenet that is equal to the number break the loop so it will get overwritten if(ary->ptr[location] == num){ break; } } //Everything that is left after finding the correct element gets bumped forward one element for(++location;location < ary->size;++location){ ary->ptr[location - 1] = ary->ptr[location]; } //Take size down one to compensate for removing an element --ary->size; } //This funciton removes the element at loc from the array void removeLocationDynamicInt64Array(struct DynamicInt64Array* ary, uint64_t loc){ //If NULL was passed to the function as an array do nothing if(ary == NULL){ return; } //Start at the location that you are trying to remove and move every element down one for(uint64_t location = loc + 1;location < ary->size;++location){ ary->ptr[location - 1] = ary->ptr[location]; } //Take size down one to compensate for removing an element --ary->size; } //This function returns the element of the array at loc int64_t getDynamicInt64Array(struct DynamicInt64Array* ary, uint64_t loc){ //If NULL was sent to the function as an array do nothing if(ary == NULL){ return 0; } //Make sure the location is valid before returning the element if(loc < ary->size){ return ary->ptr[loc]; } else{ return 0; } } //This element returns the first location in the array where key is found. returns -1 if key is not found int64_t findDynamicInt64Array(struct DynamicInt64Array* ary, int64_t key){ //If NULL was passed to the function as an array return -1 as an error if(ary == NULL){ return -1; } //Look through the entire array, looking for at element that matches the key for(uint64_t location = 0;location < ary->size;++location){ if(ary->ptr[location] == key){ return location; } } //If you went all the way through the array without finding a match return -1 as a failure return -1; } //Returns the size of the dynamic array uint64_t sizeDynamicInt64Array(struct DynamicInt64Array* ary){ //If NULL was passed to the function as an array do nothing if(ary == NULL){ return 0; } return ary->size; } //Returns the number of elements that have been allocated for the current array uint64_t allocatedDynamicInt64Array(struct DynamicInt64Array* ary){ //If NULL was passed to the function as an array do nothing if(ary == NULL){ return 0; } return ary->allocated; } //This is a function that performs a bubble sort on a DynamicInt64Array void bubbleSortDynamicInt64Array(struct DynamicInt64Array* ary){ //Keep track of the elements that have been sorted for(int64_t sorted = 0;sorted < ary->size;++sorted){ //Look at every element in the array, moving the largest to the back for(int64_t location = 1;location < (ary->size - sorted);++location){ //If the current element is smaller than the last swap them if(ary->ptr[location] < ary->ptr[location - 1]){ int64_t temp = ary->ptr[location]; ary->ptr[location] = ary->ptr[location - 1]; ary->ptr[location - 1] = temp; } } } } //This is a helper function of quickSortInt64Array. It chooses a pivot element and sorts everything to larger and smaller sides uint64_t partitionInt64Array(int64_t* ary, uint64_t bottom, uint64_t top){ int64_t pivot = ary[top]; //Choose a pivot element int64_t smaller = bottom - 1; //Keep track of the location of all elements smaller than pivot //Loop through the array, looking for elements that are smaller than pivot and move them to the front of the array for(uint64_t location = bottom;location < top;++location){ //If the current element is smaller than the pivot move it to the front of the array and move the tracker if(ary[location] < pivot){ ++smaller; //Increment the smaller than location tracker //Swap the element to the correct location int64_t temp = ary[location]; ary[location] = ary[smaller]; ary[smaller] = temp; } } //Move the pivot element to the corrent location ++smaller; int64_t temp = ary[smaller]; ary[smaller] = ary[top]; ary[top] = temp; //Return the location of the pivot element return smaller; } //This function helps quickSort a DynamicInt64Array void quickSortInt64Array(int64_t* ary, uint64_t bottom, uint64_t top){ //Make sure you are working on a valid section of the array if(bottom < top){ //Get the pivot location uint64_t pivot = partitionInt64Array(ary, bottom, top); //Sort everything smaller than the pivot quickSortInt64Array(ary, bottom, pivot - 1); //Sort everything larger than the pivot quickSortInt64Array(ary, pivot + 1, top); } } //This is a function that performs a quick sort on a DynamicInt64Array void quickSortDynamicInt64Array(struct DynamicInt64Array* ary){ quickSortInt64Array(ary->ptr, 0, ary->size - 1); } //This is a function to determine if an array is already sorted correctly bool isSortedDynamicInt64Array(struct DynamicInt64Array* ary){ //Look at every element in the array looking for elements that are out of order for(int cnt = 1;cnt < ary->size;++cnt){ //If the current element is smaller than the last element return false if(ary->ptr[cnt] < ary->ptr[cnt - 1]){ return false; } } //If you found no elements out of order then the array is sorted. return true return true; } //Compares 2 DynamicInt64Array. Returns 0 if equal, -1 if ary1 is < ary2, and 1 if ary1 > ary2 int compareDynamicInt64Array(struct DynamicInt64Array* ary1, struct DynamicInt64Array* ary2){ //Make sure they are the same size if(ary1->size < ary2->size){ return -1; } //Step through every element in each array, checking that they are the same for(uint64_t location = 0;location < ary1->size;++location){ //If an element is not the same see if ary1 is larger or smaller than ary2 if(ary1->ptr[location] != ary2->ptr[location]){ if(ary1->ptr[location] < ary2->ptr[location]){ return -1; } else{ return 1; } } } //If it made it all the way through the loop without triggering an inequality they are equal return 0; } //Performs a deep copy on a DynamicInt64Array void copyDynamicInt64Array(struct DynamicInt64Array* ary1, struct DynamicInt64Array* ary2){ //Make sure the second array is empty if(ary2->size != 0){ destroyDynamicInt64Array(ary2); initDynamicInt64Array(ary2); } //Reserve the propper amount of space reserveDynamicInt64Array(ary2, ary1->size); //Look through every element in the first array and copy it to the second for(uint64_t location = 0;location < ary1->size;++location){ pushBackDynamicInt64Array(ary2, ary1->ptr[location]); } } //This function returns the sum of all elements in a DynamicInt64Array int64_t getSumDynamicInt64Array(struct DynamicInt64Array* ary){ int64_t sum = 0; //Look through every element in the array, adding the numbers to a running sum for(uint64_t location = 0;location < ary->size;++location){ sum += ary->ptr[location]; } //Return the sum return sum; } //This function returns the product of all elements in a DynamicInt64Array int64_t getProdDynamicInt64Array(struct DynamicInt64Array* ary){ int64_t product = 1; //Look through every element in the array, multiplying it for(uint64_t location = 0;location < ary->size;++location){ product *= ary->ptr[location]; } //Return the product return product; } #endif //DYNAMIC_ARRAY_H