one-file-projects/list.cpp
2015-11-11 20:17:13 +01:00

178 lines
3.5 KiB
C++

#include <iostream>
#include <assert.h>
using namespace std;
template <class T>
class List {
private:
T* data;
int* next;
int* free;
int head;
int current;
int size;
int next_free;
public:
List(int size);
bool insert(T e);
bool remove();
bool find_first();
bool find_next();
bool find_prior();
bool find_last();
bool find(T e);
bool full();
bool empty();
T retrieve();
void update(T e);
};
template <class T>
List<T>::List(int size) : size(size), head(-1), current(-1), next_free(size-1) {
this->data = new T[size];
this->next = new int[size];
this->free = new int[size];
for(int i = 0; i < size; i++) {
this->next[i] = -1;
this->free[i] = i;
}
}
template <class T>
bool List<T>::full() {
return (this->next_free == -1);
}
template <class T>
bool List<T>::empty() {
return (this->head == -1);
}
template <class T>
bool List<T>::insert(T e) {
if(this->full()) return false;
int p = this->free[next_free--];
this->data[p] = e;
if(this->empty()) {
this->head = p;
} else {
this->next[p] = this->next[this->current];
this->next[this->current] = p;
}
this->current = p;
return true;
}
template <class T>
bool List<T>::find(T e) {
if(!this->find_first()) return false;
do {
if(this->retrieve() == e){
return true;
}
} while(this->find_next());
return false;
}
template <class T>
bool List<T>::find_prior() {
if(this->empty()) return false;
int p = this->head;
while(p!=-1 && this->next[p] != this->current) {
p = this->next[p];
}
if(p == -1) {
return false;
} else {
this->current = p;
return true;
}
}
template <class T>
bool List<T>::remove() {
if(this->empty()) return false;
int node_rem = this->current;
if(node_rem == this->head) {
this->head = this->next[node_rem];
this->current = this->head;
} else {
assert(this->find_prior());
this->next[this->current] = this->next[node_rem];
}
this->next[node_rem] = -1;
this->free[++this->next_free] = node_rem;
return true;
}
template <class T>
bool List<T>::find_next() {
if(this->empty()) return false;
if(this->next[this->current] == -1) return false;
this->current = this->next[this->current];
return true;
}
template <class T>
bool List<T>::find_first() {
if(this->empty()) return false;
this->current = this->head;
return true;
}
template <class T>
bool List<T>::find_last() {
if(!this->find_first()) return false;
while(this->find_next());
return true;
}
template <class T>
T List<T>::retrieve() {
assert(!this->empty());
return this->data[current];
}
template <class T>
void List<T>::update(T e) {
assert(!this->empty());
this->data[current] = e;
}
int main( int argc, char *argv[] ) {
List<int> l(20);
int i;
for(i = 0; !l.full(); i++) {
l.insert(i);
}
assert(i == 20);
// Delete half
l.find_first();
for(i = 0; i < 10; i++) l.remove();
// Delete 14
assert(l.find(14));
assert(l.remove());
assert(!l.find(14));
assert()
// Show values
assert(l.find_first());
do {
cout << l.retrieve() << endl;
} while(l.find_next());
// Delete all
assert(l.find_first());
while(!l.empty()) l.remove();
assert(!l.find_first());
return 0;
}