Files
CClasses/DynamicInt64Array.h

367 lines
11 KiB
C

//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 <https://www.gnu.org/licenses/>.
*/
#ifndef DYNAMIC_ARRAY_H
#define DYNAMIC_ARRAY_H
#include <stdlib.h>
#include <inttypes.h>
#include <stdbool.h>
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