mirror of
https://github.com/tiennm99/CTDL-GT.git
synced 2026-06-09 22:11:20 +00:00
224 lines
6.0 KiB
C++
224 lines
6.0 KiB
C++
#include "UnrolledLinkedList.h"
|
|
|
|
void UnrolledLinkedList::add(int val)
|
|
{
|
|
if (tail == nullptr) {
|
|
tail = new Node(nodeSize);
|
|
++numOfNodes;
|
|
head = tail;
|
|
} else if (tail->isFull()) {
|
|
Node *newNode = new Node(nodeSize);
|
|
++numOfNodes;
|
|
newNode->prev = tail;
|
|
tail->next = newNode;
|
|
int hsize = getHalfNodeSize();
|
|
memmove(newNode->elements, tail->elements + hsize, (nodeSize - hsize) * sizeof(int));
|
|
tail->numElements = hsize;
|
|
newNode->numElements = nodeSize - hsize;
|
|
tail = newNode;
|
|
}
|
|
tail->add(val);
|
|
++size;
|
|
}
|
|
|
|
int UnrolledLinkedList::getAt(int pos)
|
|
{
|
|
if (pos < 0 || pos >= size)
|
|
throw "IndexOutOfBoundsException";
|
|
int cnt = 0;
|
|
Node *temp = head;
|
|
while (cnt + temp->numElements <= pos) {
|
|
cnt += temp->numElements;
|
|
temp = temp->next;
|
|
}
|
|
return temp->elements[pos - cnt];
|
|
}
|
|
|
|
void UnrolledLinkedList::setAt(int pos, int val)
|
|
{
|
|
if (pos < 0 || pos >= size)
|
|
throw "IndexOutOfBoundsException";
|
|
int cnt = 0;
|
|
Node *temp = head;
|
|
while (cnt + temp->numElements <= pos) {
|
|
cnt += temp->numElements;
|
|
temp = temp->next;
|
|
}
|
|
temp->elements[pos - cnt] = val;
|
|
}
|
|
|
|
void UnrolledLinkedList::insertAt(int pos, int val)
|
|
{
|
|
if (pos < 0 || pos > size)
|
|
throw "IndexOutOfBoundsException";
|
|
if (pos == size) {
|
|
add(val);
|
|
return;
|
|
}
|
|
int cnt = 0;
|
|
Node *temp = head;
|
|
while (cnt + temp->numElements <= pos) {
|
|
cnt += temp->numElements;
|
|
temp = temp->next;
|
|
}
|
|
if (temp->isFull()) {
|
|
Node *newNode = new Node(nodeSize);
|
|
++numOfNodes;
|
|
if (temp == tail)
|
|
tail = newNode;
|
|
else
|
|
temp->next->prev = newNode;
|
|
newNode->prev = temp;
|
|
newNode->next = temp->next;
|
|
temp->next = newNode;
|
|
int hsize = getHalfNodeSize();
|
|
if (pos - cnt >= hsize) {
|
|
memmove(newNode->elements, temp->elements + hsize, (nodeSize - hsize) * sizeof(int));
|
|
temp->numElements = hsize;
|
|
newNode->numElements = nodeSize - hsize;
|
|
newNode->insertAt(pos - cnt - hsize, val);
|
|
} else {
|
|
memmove(newNode->elements, temp->elements + hsize - 1, (nodeSize - hsize + 1) * sizeof(int));
|
|
temp->numElements = hsize - 1;
|
|
newNode->numElements = nodeSize - hsize + 1;
|
|
temp->insertAt(pos - cnt, val);
|
|
}
|
|
} else {
|
|
temp->insertAt(pos - cnt, val);
|
|
}
|
|
++size;
|
|
}
|
|
|
|
void UnrolledLinkedList::deleteAt(int pos)
|
|
{
|
|
if (pos < 0 || pos >= size)
|
|
throw "IndexOutOfBoundsException";
|
|
int cnt = 0;
|
|
Node *temp = head;
|
|
while (cnt + temp->numElements <= pos) {
|
|
cnt += temp->numElements;
|
|
temp = temp->next;
|
|
}
|
|
temp->removeAt(pos - cnt);
|
|
--size;
|
|
if (size == 0) {
|
|
delete head;
|
|
--numOfNodes;
|
|
head = nullptr;
|
|
tail = nullptr;
|
|
return;
|
|
}
|
|
if (temp->isUnderHalfFull()) {
|
|
int hsize = getHalfNodeSize();
|
|
if (temp == head) {
|
|
Node *next = temp->next;
|
|
if (next != nullptr) {
|
|
if (next->numElements <= hsize) {
|
|
memmove(temp->elements + temp->numElements, next->elements, next->numElements * sizeof(int));
|
|
temp->numElements += next->numElements;
|
|
temp->next = next->next;
|
|
if (next == tail)
|
|
tail = temp;
|
|
else
|
|
temp->next->prev = temp;
|
|
delete next;
|
|
--numOfNodes;
|
|
} else {
|
|
temp->add(next->elements[0]);
|
|
next->removeAt(0);
|
|
}
|
|
}
|
|
} else {
|
|
Node *prev = temp->prev;
|
|
if (prev->numElements <= hsize) {
|
|
memmove(prev->elements + prev->numElements, temp->elements, temp->numElements * sizeof(int));
|
|
prev->numElements += temp->numElements;
|
|
prev->next = temp->next;
|
|
if (temp == tail)
|
|
tail = prev;
|
|
else
|
|
prev->next->prev = prev;
|
|
delete temp;
|
|
--numOfNodes;
|
|
} else {
|
|
temp->insertAt(0, prev->elements[prev->numElements - 1]);
|
|
prev->removeAt(prev->numElements - 1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
int UnrolledLinkedList::firstIndexOf(int val)
|
|
{
|
|
int cnt = 0;
|
|
Node *temp = head;
|
|
while (temp != nullptr) {
|
|
for (int i = 0; i < temp->numElements; ++i) {
|
|
if (temp->elements[i] == val)
|
|
return cnt + i;
|
|
}
|
|
cnt += temp->numElements;
|
|
temp = temp->next;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int UnrolledLinkedList::lastIndexOf(int val)
|
|
{
|
|
int cnt = size;
|
|
Node *temp = tail;
|
|
while (temp != nullptr) {
|
|
cnt -= temp->numElements;
|
|
for (int i = temp->numElements - 1; i >= 0; --i) {
|
|
if (temp->elements[i] == val)
|
|
return cnt + i;
|
|
}
|
|
temp = temp->prev;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
bool UnrolledLinkedList::contains(int val)
|
|
{
|
|
Node *temp = head;
|
|
while (temp != nullptr) {
|
|
for (int i = 0; i < temp->numElements; ++i) {
|
|
if (temp->elements[i] == val)
|
|
return true;
|
|
}
|
|
temp = temp->next;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void UnrolledLinkedList::reverse()
|
|
{
|
|
if (size < 2)
|
|
return;
|
|
Node *temp = head;
|
|
while (temp != nullptr) {
|
|
Node *prev = temp->prev;
|
|
Node *next = temp->next;
|
|
temp->reverse();
|
|
temp->next = prev;
|
|
temp->prev = next;
|
|
temp = next;
|
|
}
|
|
temp = head;
|
|
head = tail;
|
|
tail = temp;
|
|
}
|
|
|
|
int *UnrolledLinkedList::toArray()
|
|
{
|
|
int *arr = new int[size];
|
|
int cnt = 0;
|
|
Node *temp = head;
|
|
while (temp != nullptr) {
|
|
memcpy(arr + cnt, temp->elements, temp->numElements * sizeof(int));
|
|
cnt += temp->numElements;
|
|
temp = temp->next;
|
|
}
|
|
return arr;
|
|
}
|