Files
secondo/Algebras/Periodic/List2.h

524 lines
8.5 KiB
C
Raw Permalink Normal View History

2026-01-23 17:03:45 +08:00
/*
1 The File List2.h
*/
#ifndef LIST_H
#define LIST_H
#ifndef NULL
#define NULL 0
#endif
namespace periodic{
// forward declaration of the list class
template<class T>class List;
// forward declaration of the Iterator class
template<class T> class Iterator;
/*
1.1 The Class Element
This class provides Elements for a double linked list.
*/
template<class T>
class Element{
friend class List<T>;
friend class Iterator<T>;
public:
/*
~Constructor~
Creates a new element whith the given entry.
*/
Element(T entry){
this->entry=entry;
next=NULL;
prev=NULL;
}
/*
~Connect~
Connects this element with the argument.
*/
void Connect(Element* e){
this->next= e;
e->prev=this;
}
/*
~Destructor~
The destructor does nothing. To delete the entry of the element,
use the destroy function first.
*/
~Element(){}
/*
~Destroy~
This function deletes the entry of this element. This should only be
used in combination with the destructor.
*/
void Destroy(){
entry = 0;
}
/*
~GetEntry~
Returns the content of this element.
*/
T GetEntry(){
return entry;
}
/*
~GetNext~
*/
Element<T>* GetNext(){ return next;}
/*
~GetPrev~
*/
Element<T>* GetPrev(){ return prev; }
private:
T entry;
Element<T>* next;
Element<T>* prev;
};
/*
1.2 The Class List
This class provides a double linked list with operations to
insert, delete, and iterating over elements.
*/
template<class T>
class List{
friend class Iterator<T>;
public:
/**
~Constructor~
This constructor creates a new empty double linked list.
*/
List(){
first=NULL;
last=NULL;
current=NULL;
length=0;
}
/*
~IsEmpty~
This function returns true iff the list does not contain
any element.
*/
bool IsEmpty(){
return first==0;
}
/**
~Append function~
This function appends a new element at the end of the list.
The position of the current element is not influenced by this
operation except the list original list was empty.
*/
void Append(T entry){
Element<T> *ne = new Element<T>(entry);
if(!last){ // the first element
first = ne;
current = ne;
last = ne;
}else{
last->Connect(ne);
last=ne;
}
length++;
}
/**
~The Insert function~
This function inserts a new element before the current element.
The new element will be also the new current element. For inserting
an element at the end of the list, use the append function.
*/
void Insert(T entry){
Element<T>* ne = new Element<T>(entry);
if(!current){ // special case : list is empty
first = ne;
last = ne;
current=ne;
}else if(current==first){ // special case: the first element
ne->connect(first);
current=ne;
first=ne;
}else{ // normal case: insert in the middle
Element<T>* prev = current->prev;
prev->connect(ne);
ne->connect(current);
current=ne;
}
length++;
}
/**
~Contains function~
This function checks whether the given element is a member of
this list.
*/
bool Contains(T entry){
Element<T>* scan = first;
while(scan){
if((scan->entry)==entry)
return true;
scan = scan->next;
}
return false;
}
/**
~The GoStart function~
This function sets the current element of the list to
the begin of the list.
*/
void GoStart(){
current = first;
}
/**
~The GoEnd function~
When calling this function, the current element of this list is
set to the last element of this list.
*/
void GoEnd(){
current = last;
}
/**
~GoNext~
This function moves the current element one position to behind.
If the list is empty or the current element is already at the end of this
list, the list remains unchanged. The return value is an indicator for the
success of this function.
*/
bool GoNext(){
if(current==last){ //is also the case when the list is empty
return false;
}
current = current->GetNext();
return true;
}
/*
~GoBack~
This function moves the current element back one position if possible.
*/
bool GoBack(){
if(current==first) // also if the list is empty
return false;
current = current->prev;
return true;
}
/*
~OnEnd~
This function returns false if after the current element at leat one
further element exists.
*/
bool OnEnd(){
return current==last;
}
/*
~OnStart~
This function returns true if the current element is at the begin of the list.
*/
bool OnStart(){
return current==first;
}
/*
~Get~
This function returns the element under the cursor. If the list is empty,
the return value will be NULL.
*/
T Get(){
if(!current)
return NULL;
return current->entry;
}
/*
~GetFirst~
Returns the fisrt element from this list. If this list is empty,
NULL is returned.
*/
T GetFirst(){
if(!first) return NULL;
return first->entry;
}
/*
~ GetLast~
Returns the last element from this list. If the list is
empty, null will be returned.
*/
T GetLast(){
if(!last) return NULL;
else return last->entry;
}
/*
~Delete~
This function deletes the element under the cursor. The new current element
will be the element after the original one if available otherwise the
element before it.
*/
bool Delete(){
if(!current)
return false;
Element<T>* victim = current;
if(current==first){ // remove the first element
current = current->GetNext();
first= current;
if(current){
current->prev=NULL;
}else{
if(victim==last) // the only element in this list
last = NULL;
}
delete victim;
} else if(current==last){ //remove the last element;
last = last->prev;
current=last;
if(current)
current->next = NULL;
delete victim;
}else{ // normal case delete in the middle
current = current->next;
(victim->prev)->connect(current);
delete victim;
}
length--;
return true;
}
/*
~Destructor~
This destructor removes all elements from the list. Because the
destroy function of the elements is not called within this function,
the content in the elements are not deallocated.
*/
~List(){
while(first){
current=first;
first=first->next;
delete(current);
}
}
/*
~Destroy~
This function removes all elements of this list. Also the
content of the single entries is removed. After calling this
function, the list will be empty.
*/
void Destroy(){
while(first){
current=first;
first=first->next;
current->Destroy();
delete current;
}
first = current = last = 0;
length=0;
}
/*
~GetLength~
This function computes the length of this list.
In a later version isd would be better to store the
length in an extra member.
*/
int GetLength()const{
return length;
}
/*
~ConvertToArray~
This function creates a new array containing the
elements in the list. The caller has to deallocate
the memory occupied by this array.
*/
T* ConvertToArray(){
T* res = new T[length];
Element<T>* scan = first;
int pos=0;
while(scan){
res[pos++]=scan->entry;
scan = scan->next;
}
return res;
}
private:
Element<T>* first;
Element<T>* last;
Element<T>* current;
int length;
};
/*
1.3 An Iterator class
Note that you can't change (insert,delete,append) the list when
you use an iterator on it.
*/
template<class T> class Iterator{
public:
/*
~Constructor~
*/
Iterator(List<T>* L){
this->elem = L->first;
this->L = L;
}
/*
~Reset~
This function sets the position of this iterator to the
begin of the list.
*/
void Reset(){
elem = L->first;
}
/*
~HasNext~
This function checks whether a further element is available.
*/
bool HasNext(){
return (elem!=0);
}
/*
~Next~
This function returns the next value of this iterator if available.
If no next element exists (check it by the HasNext function), the
result will be undefined.
*/
T Next(){
T res;
res = elem->entry;
elem = elem->next;
return res;
}
/*
~SetList~
Changes this iterator to be an iterator on the argument.
*/
void SetList(List<T> l){
this->L = l;
this->elem=L->first;
}
private:
List<T>* L;
Element<T>* elem;
};
} // namespace periodic
#endif