INF205/lab_3/sequences-int/dynamic-array.cpp
2024-03-12 20:52:05 +01:00

103 lines
3.1 KiB
C++

#include <algorithm>
#include <cassert>
#include <iostream>
#include "queue.h"
#include "dynamic-array.h"
using namespace seq;
// remove all the items from the array
void DynamicArray::clear()
{
if(this->values) delete this->values;
this->values = nullptr;
this->logical_size = 0;
this->capacity = 0;
}
void DynamicArray::enqueue(int value)
{
int i = this->logical_size;
// catch the case where capacity is exhausted and we need to allocate more memory
if(this->logical_size == this->capacity)
{
size_t new_capacity = 2 * this->capacity;
if(new_capacity == 0) new_capacity = 1;
this->resize(new_capacity);
}
assert(this->capacity > this->logical_size);
// shift all elements from index i onward one to the right
// we use a temporary storage and copy() from <algorithm> to do this efficiently
size_t shifted_elements = this->logical_size - i;
if(shifted_elements > 0)
{
int* temp_storage = new int[shifted_elements]();
// copy values[i] to values[i+shifted_elements-1] into temp_storage
std::copy(this->values + i, this->values + i + shifted_elements, temp_storage);
// copy all of temp_storage into values[i+1] to values[logical_size]
std::copy(temp_storage, temp_storage + shifted_elements, &this->values[i+1]);
delete[] temp_storage;
}
// now we can write the inserted item into values[i]
this->logical_size++;
this->values[i] = value;
}
int DynamicArray::dequeue()
{
if (this->size() == 0) {
return 0;
}
int i = 0;
// Save the first element wich we want to return:
int outgoing = this->values[0];
// shift all elements from onward one to the left
size_t shifted_elements = this->logical_size - 1;
int* temp_storage = new int[shifted_elements]();
// copy values[i+1] to values[logical_size-1] into temp_storage
std::copy(this->values + 1, this->values + this->logical_size, temp_storage);
// copy all of temp_storage into values[i] to values[logical_size-2]
std::copy(temp_storage, temp_storage + shifted_elements, &this->values[i]);
delete[] temp_storage;
if (!this->empty()) {
this->logical_size--; // with this, we are done with the task
// now let us see whether we have deleted so many items that we should resize to save memory
if(this->capacity/2 >= this->logical_size) this->resize(this->capacity/2);
}
return outgoing;
}
// allocate static array with "new_capacity" elements,
// copy the contents there, and delete the previous static array
void DynamicArray::resize(size_t new_capacity)
{
assert(new_capacity >= this->logical_size);
int* allocated_memory = new int[new_capacity]();
if(this->values != nullptr)
{
// use <algorithm> library construct for efficient memory-level copying
// take values[0] to values[logical-size-1] and copy it into allocated_memory
std::copy(this->values, this->values + this->logical_size, allocated_memory);
delete this->values; // now we can delete the old storage
}
// update class properties
this->values = allocated_memory;
this->capacity = new_capacity;
}