-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDynamicArray.hpp
More file actions
239 lines (207 loc) · 8.5 KB
/
Copy pathDynamicArray.hpp
File metadata and controls
239 lines (207 loc) · 8.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
#pragma once
#include <algorithm>
#include <iostream>
template<typename T>
class DynamicArray {
public:
DynamicArray(); //Konstruktor
DynamicArray(int initialCapacity); // konstruktor z pojemnością
~DynamicArray(); //Destruktor
DynamicArray(const DynamicArray& other); //Konstruktor kopiujący
DynamicArray(DynamicArray&& other) noexcept; // konstruktor przenoszący
DynamicArray<T>& operator=(const DynamicArray<T>& other); // operator przypisania kopiujący
DynamicArray<T>& operator=(DynamicArray<T>&& other) noexcept; // operator przypisania przenoszący
void pushFront(const T& value); //Dodaje element na początek tablicy
void pushBack(const T& value); //Dodaje element na koniec tablicy
void pushAt(int index, const T& value); //Dodaje element na określonej pozycji w tablicy
void popFront(); //Usuwa pierwszy element z tablicy
void popBack(); //Usuwa ostatni element z tablicy
void popAt(int index); //Usuwa element z określonej pozycji w tablicy
T& operator[](int index); //Przeciążenie operatora [], umożliwiające dostęp do elementów tablicy za pomocą indeksu
const T& operator[](int index) const; //Przeciążenie operatora [] dla stałych obiektów, umożliwiające dostęp do elementów tablicy za pomocą indeksu
T get(int index) const; //Zwraca wartość elementu na określonej pozycji w tablicy
void set(int index, const T& value); //Zmienia wartość elementu na określonej pozycji w tablicy
void swap(int i, int j); //Zamienia miejscami dwa elementy w tablicy
void reserve(int newCapacity); //Rezerwuje pamięć dla co najmniej newCapacity elementów, zwiększając pojemność tablicy, jeśli jest to konieczne
int getSize() const { return size; } //Zwraca aktualny rozmiar tablicy
int getCapacity() const { return capacity; } //Zwraca aktualną pojemność tablicy
private:
T* data; //Wskaźnik na dynamiczną tablicę
int size; //Aktualny rozmiar tablicy
int capacity; //Aktualna pojemność tablicy
void resize(); //Funkcja do zmiany rozmiaru tablicy, gdy jest pełna
};
template<typename T>
DynamicArray<T>::DynamicArray() : data(nullptr), size(0), capacity(0) {} // Konstruktor inicjalizujący wskaźnik na tablicę jako nullptr, rozmiar jako 0 i pojemność jako 4
template<typename T>
DynamicArray<T>::DynamicArray(int initialCapacity)
: size(0), capacity(initialCapacity)
{
data = new T[capacity](); // Alokujemy dynamiczną tablicę o określonej pojemności i inicjalizujemy ją wartościami domyślnymi typu T
}
template<typename T>
DynamicArray<T>::~DynamicArray() { // Destruktor zwalniający pamięć zajmowaną przez tablicę
delete[] data;
}
template<typename T>
DynamicArray<T>::DynamicArray(const DynamicArray<T>& other) : size(other.size), capacity(other.capacity) // Konstruktor kopiujący, który tworzy nową tablicę o tej samej pojemności i kopiuje elementy z innej tablicy
{
if (capacity == 0) {
data = nullptr;
return;
}
data = new T[capacity](); // Alokujemy nową tablicę o tej samej pojemności
std::copy(other.data, other.data + size, data); // Kopiujemy elementy z innej tablicy do nowej tablicy
}
template<typename T>
DynamicArray<T>::DynamicArray(DynamicArray<T>&& other) noexcept // Konstruktor przenoszący, który przejmuje zasoby innej tablicy, ustawiając jej wskaźnik na nullptr i rozmiar oraz pojemność na 0
: data(other.data), size(other.size), capacity(other.capacity)
{
other.data = nullptr;
other.size = 0;
other.capacity = 0;
}
template<typename T>
DynamicArray<T>& DynamicArray<T>::operator=(const DynamicArray<T>& other) { // Operator przypisania kopiujący, który zwalnia istniejącą tablicę, tworzy nową tablicę o tej samej pojemności i kopiuje elementy z innej tablicy
if (this == &other) return *this; // Sprawdzamy, czy przypisujemy do samego siebie, jeśli tak, to nie robimy nic
T* newData = nullptr; // Tworzymy nową tablicę, jeśli pojemność jest większa niż 0
if (other.capacity > 0) {
newData = new T[other.capacity]();
std::copy(other.data, other.data + other.size, newData); // Kopiujemy elementy z innej tablicy do nowej tablicy
}
delete[] data; // Zwalniamy istniejącą tablicę
data = newData; // Zmieniamy wskaźnik na nową tablicę
size = other.size; // Aktualizujemy rozmiar i pojemność
capacity = other.capacity;
return *this; // Zwracamy referencję do bieżącego obiektu, umożliwiając łańcuchowe przypisania
}
template<typename T>
DynamicArray<T>& DynamicArray<T>::operator=(DynamicArray<T>&& other) noexcept { // Operator przypisania przenoszący, który zwalnia istniejącą tablicę, przejmuje zasoby innej tablicy i ustawia jej wskaźnik na nullptr oraz rozmiar i pojemność na 0
if (this != &other) {
delete[] data;
data = other.data;
size = other.size;
capacity = other.capacity;
other.data = nullptr;
other.size = 0;
other.capacity = 0;
}
return *this;
}
template<typename T>
void DynamicArray<T>::reserve(int newCapacity) {
if (newCapacity <= capacity) return; // Jeśli nowa pojemność jest mniejsza lub równa aktualnej, nie robimy nic
T* newData = new T[newCapacity]();
if (data) {
std::copy(data, data + size, newData); // Kopiujemy istniejące elementy do nowej tablicy
delete[] data;
}
data = newData; // Zmieniamy wskaźnik na nową tablicę
capacity = newCapacity;
}
template<typename T>
void DynamicArray<T>::pushFront(const T& value) {
if (size == capacity) { // Sprawdzamy czy tablica jest pełna
resize(); // Jeśli tak, to zwiększamy jej pojemność
}
for (int i = size - 1; i >= 0; --i) { // Przesuwamy wszystkie elementy o jedno miejsce w prawo
data[i + 1] = data[i];
}
data[0] = value; // Dodajemy nowy element na początek tablicy
size++; // Zwiększamy rozmiar
}
template<typename T>
void DynamicArray<T>::pushBack(const T& value) {
if (size == capacity) { // Sprawdzamy czy tablica jest pełna
resize(); // Jeśli tak, to zwiększamy jej pojemność
}
data[size++] = value; // Dodajemy nowy element na koniec tablicy i zwiększamy rozmiar
}
template<typename T>
void DynamicArray<T>::pushAt(int index, const T& value) {
if (index < 0 || index > size) return;
if (index == 0) { // Jeśli indeks to 0, dodajemy element na początek tablicy
pushFront(value);
}
else if (index == size) { // Jeśli indeks to rozmiar, dodajemy element na koniec tablicy
pushBack(value);
}
else {
if (size == capacity) {
resize();
}
for (int i = size; i > index; --i) { // Przesuwamy wszystkie elementy od indeksu do końca o jedno miejsce w prawo
data[i] = data[i - 1];
}
data[index] = value;
++size;
}
}
template<typename T>
void DynamicArray<T>::popFront() {
if (size > 0) {
for (int i = 0; i < size - 1; i++) { // Przesuwamy wszystkie elementy o jedno miejsce w lewo
data[i] = data[i + 1];
}
size--; // Zmniejszamy rozmiar
}
}
template<typename T>
void DynamicArray<T>::popBack() {
if (size > 0) {
size--; // Zmniejszamy rozmiar, usuwając ostatni element
}
}
template<typename T>
void DynamicArray<T>::popAt(int index) {
if (index < 0 || index >= size) return;
if (index == 0) { // Jeśli indeks to 0, usuwamy element z początku tablicy
popFront();
}
else if (index == size - 1) { // Jeśli indeks to rozmiar - 1, usuwamy element z końca tablicy
popBack();
}
else {
for (int i = index; i < size - 1; i++) { // Przesuwamy wszystkie elementy od indeksu do końca o jedno miejsce w lewo
data[i] = data[i + 1];
}
size--;
}
}
template<typename T>
void DynamicArray<T>::resize() {
if (capacity == 0) {
capacity = 1; // Jeśli pojemność jest 0, ustawiamy ją na 1
}
else {
capacity *= 2; // Podwajamy pojemność
}
T* newData = new T[capacity];
if (data) {
std::copy(data, data + size, newData);
}
delete[] data;
data = newData;
}
template<typename T>
T& DynamicArray<T>::operator[](int index) { // Przeciążenie operatora [], umożliwiające dostęp do elementów tablicy za pomocą indeksu
return data[index];
}
template<typename T>
const T& DynamicArray<T>::operator[](int index) const { // Przeciążenie operatora [] dla stałych obiektów, umożliwiające dostęp do elementów tablicy za pomocą indeksu
return data[index];
}
template<typename T>
T DynamicArray<T>::get(int index) const { // Zwraca wartość elementu na określonej pozycji w tablicy
return data[index];
}
template<typename T>
void DynamicArray<T>::set(int index, const T& value) { // Zmienia wartość elementu na określonej pozycji w tablicy
data[index] = value;
}
template<typename T>
void DynamicArray<T>::swap(int i, int j) { // Zamienia miejscami dwa elementy w tablicy
T temp = data[i];
data[i] = data[j];
data[j] = temp;
}