159 lines
3.1 KiB
C++
159 lines
3.1 KiB
C++
|
#include "ll.h"
|
||
|
|
||
|
ll::ll(): _size(0), head(NULL), tail(NULL) {
|
||
|
}
|
||
|
|
||
|
ll::~ll() {
|
||
|
clear();
|
||
|
}
|
||
|
|
||
|
void ll::insertHead(int value) {
|
||
|
if(value < 0 or find(value)) {
|
||
|
return;
|
||
|
}
|
||
|
if(head == NULL) {
|
||
|
assert(tail == NULL);
|
||
|
assert(_size == 0);
|
||
|
head = new node(value);
|
||
|
tail = head;
|
||
|
}
|
||
|
else {
|
||
|
node * tmp = head;
|
||
|
head = new node(value);
|
||
|
head->next = tmp;
|
||
|
}
|
||
|
_size++;
|
||
|
}
|
||
|
|
||
|
void ll::insertTail(int value) {
|
||
|
if(value < 0 or find(value)) {
|
||
|
return;
|
||
|
}
|
||
|
if(tail == NULL) {
|
||
|
assert(head == NULL);
|
||
|
assert(_size == 0);
|
||
|
tail = new node(value);
|
||
|
head = tail;
|
||
|
}
|
||
|
else {
|
||
|
node * tmp = tail;
|
||
|
tmp->next = new node(value);
|
||
|
tail = tmp->next;
|
||
|
}
|
||
|
_size++;
|
||
|
}
|
||
|
|
||
|
void ll::insertAfter(int value, int insertionNode) {
|
||
|
if(value < 0 or find(value)) {
|
||
|
return;
|
||
|
}
|
||
|
node * inlist = find(insertionNode);
|
||
|
if(not inlist) {
|
||
|
return;
|
||
|
}
|
||
|
node * toinsert = new node(value);
|
||
|
if(inlist == tail) {
|
||
|
tail = toinsert;
|
||
|
}
|
||
|
toinsert->next = inlist->next;
|
||
|
inlist->next = toinsert;
|
||
|
_size++;
|
||
|
}
|
||
|
|
||
|
void ll::remove(int value) {
|
||
|
if(not find(value)) {
|
||
|
// should deal with empty list, and not found
|
||
|
return;
|
||
|
}
|
||
|
else if(head == tail) {
|
||
|
delete head;
|
||
|
head = tail = NULL;
|
||
|
_size--;
|
||
|
}
|
||
|
else {
|
||
|
node * cur = head;
|
||
|
if(head->value == value) {
|
||
|
head = head->next;
|
||
|
delete cur;
|
||
|
_size--;
|
||
|
}
|
||
|
else {
|
||
|
while(cur) {
|
||
|
if(cur->next == NULL) {
|
||
|
// removing end ...
|
||
|
break;
|
||
|
}
|
||
|
if(cur->next->value == value) {
|
||
|
node * to_remove = cur->next;
|
||
|
if(to_remove == tail) {
|
||
|
tail = cur;
|
||
|
}
|
||
|
cur->next = to_remove->next;
|
||
|
delete to_remove;
|
||
|
_size--;
|
||
|
}
|
||
|
cur = cur->next;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ll::clear() {
|
||
|
node * tmp = head;
|
||
|
while(head) {
|
||
|
tmp = head;
|
||
|
head = head->next;
|
||
|
delete tmp;
|
||
|
_size--;
|
||
|
}
|
||
|
head = tail = NULL;
|
||
|
assert(_size == 0);
|
||
|
}
|
||
|
|
||
|
int ll::at(int index) {
|
||
|
if (index >= _size or index < 0) {
|
||
|
return -1;
|
||
|
}
|
||
|
node * tmp = head;
|
||
|
for(int i = 0; i < index; i++) {
|
||
|
tmp = tmp->next;
|
||
|
}
|
||
|
if(tmp == NULL) {
|
||
|
return -1;
|
||
|
}
|
||
|
else {
|
||
|
return tmp->value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int ll::size() {
|
||
|
return _size;
|
||
|
}
|
||
|
|
||
|
node * ll::find(int value) {
|
||
|
node * tmp = head;
|
||
|
while(tmp) {
|
||
|
if(tmp->value == value) {
|
||
|
return tmp;
|
||
|
}
|
||
|
tmp = tmp->next;
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
ostream & operator<<(ostream & os, const node & n) {
|
||
|
os << n.value;
|
||
|
return os;
|
||
|
}
|
||
|
|
||
|
ostream & operator<<(ostream & os, const ll & l) {
|
||
|
os << "ll {(" << l._size << ") ";
|
||
|
node * cur = l.head;
|
||
|
while (cur) {
|
||
|
os << *cur << ", ";
|
||
|
cur = cur->next;
|
||
|
}
|
||
|
os << "}";
|
||
|
return os;
|
||
|
}
|