Lists List: finite sequence of data elements all elements have the same data type The operations depend on the type of the list and not on the data type List: the most general type Ordered: element is ascending order Stacks, Queues: not all operations are allowed E.G.M. Petrakis lists
Insertion after current list or head info next list new element Insertion after current position current rear or tail E.G.M. Petrakis lists
Insertion at current position list or head list new element Insertion at current position current rear or tail E.G.M. Petrakis lists
Deletion after current list or head deleted element Deletion after current position current rear or tail E.G.M. Petrakis lists
current Deletion at current position deleted element list or rear or head deleted element Deletion at current position current rear or tail E.G.M. Petrakis lists
Terminology empty: contains no elements length: number of elements in list head, or list: pointer to the beginning of the list tail: pointer to the last element current: pointer to current element ordered: elements in ascending or descending order E.G.M. Petrakis lists
Operations setFirst: set “current” to “head” setPos(i): sets current to the i-th element currValue: returns value of “current” element next/prev: “current” points to next/previous element clear: delete all elements insert: inserts an element at/after current position append: inserts an element at “tail” remove: delete the element at/after “current” position find(key): set current to the first occurrence of “key” isInList: true/false if current position is in list isEmpty: true/false if list is empty E.G.M. Petrakis lists
ADT List template <class ELEM> class list { // list class ADT in C++ public: list(const int = LIST_SIZE); // constructor ~list( ); // destructor void clear ( ); // remove all elements void insert(const ELEM &); // inset at current void append(const ELEM &); // insert at tail ELEM remove ( ); // remove current void setFirst ( ); // set current to HEAD void prev ( ) ; // set current to previous void next ( ); // set current to next int length ( ) const; // return size of list void setPos(const int); // set current to new pos void setValue(const ELEM &) // set current’s value bool isEmpty( ) const; // true/false on empty bool isInList( ) const; // true/false if current is in list bool find(const ELEM &); // find value of current }; E.G.M. Petrakis lists
Iteration Iterate through the whole list : MyList for (MyList.first( ); MyList.isInList( ); MyList.next( )) DoSomething(MyList.currValue( )); If MyList: (12 32 15) and current points to 32 then MyList.insert(90) changes the list to be (12 32 90 15) E.G.M. Petrakis lists
List Implementations Array-based: very fast the elements are stored in array static: actual number of elements less than size allocated Dynamic Memory: slower, more efficient allocates memory for new elements dynamic: no restriction on number of elements (except memory size) E.G.M. Petrakis lists
Array Implementation (1) Elements in continuous array positions Head of list at pos 0 Insertion and Deletion cause shifting of elements E.G.M. Petrakis lists
template <class ELEM> class list { //array based list class private: int msize // maximum size of list int numinlist //actual number of ELEMs int curr; // position of “current” ELEM* listarray; //array holding ELEMs public: list (const int=LIST_SIZE); // constructor ~list( ); // destructor void clear( ); // remove all ELEMs from list void insert(const ELEM &); // insert ELEM at current position void append(const ELEM &); // insert ELEM at tail of list ELEM remove( ); // remove and return current ELEM void setFirst( ); // set current to first position void prev( ); // move current to previous position void next( ); // move current to next position int length( ) const; // return current length of list void setPos(const int); // set current to specified position void setValue(const ELEM &); // set current ELEM's value ELEM currValue( ) const; // return current ELEM's value bool isEmpty( ) const; // return TRUE if list is empty bool isInList( ) const; // TRUE if current is within list bool find(const ELEM &); // find value (from current position) }; E.G.M. Petrakis lists
template <class ELEM> List<ELEM>::List(int sz) // constructor: initialize { msize = sz; numinlist = 0; curr = 0; listarray = new ELEM[sz]; } List<ELEM>::~List( ) // destructor: return array space { delete [ ] listarray; } void List<ELEM>::clear( ) // remove all Elems from list { numinlist = 0; curr = 0; } // reinitialize values void List<ELEM>::insert(const Elem item) { // insert Elem at current position // the array must not be full and “curr” must be a legal position assert((numinlist < msize) && (curr >= 0) && (curr <= numinlist)); for(int i = numinlist; i > curr; i--) // shift element up to make room listarray[i] = listarray[i - 1]; listarray[curr] = item; numinlist++; // increment current list size } E.G.M. Petrakis lists
template <class ELEM> void List<ELEM>::append(const Elem item) { // insert Elem at tail of list assert(numinlist < msize); // list must not be full listarray[numinlist++] = item; // increment list size } ELEM List<ELEM>::remove( ) { // remove and return current Elem assert( !isEmpty( ) && isInList( ) ); // must be an Elem to remove Elem temp = listarray[curr]; // store removed Elem for (int i=curr; i < numlist-1; i++) // shift elements down listarray[i] = listarray[i+1]; numinlist--; // decrement current list size return temp; void List<ELEM>::setFirst( ) // set curr to first position { curr = 0; } void List<ELEM>::prev( ) // move curr to previous position { curr--; } E.G.M. Petrakis lists
template <class ELEM> void List<ELEM>::next( ) // move curr to next position { curr++; } int List::length( ) const // return current length of list { return numinlist; } void List<ELEM>::setPos(int pos) // set curr to specified position {curr = pos; } void List<ELEM>::setValue(const Elem val) { // set current Elem's value assert(isInList( )); // curr must be at valid position listarray[curr] = val; } Elem List<ELEM>::currValue( ) const { // return current Elem's value assert(isInList( )); // must be at a valid position return listarray[curr]; E.G.M. Petrakis lists
} template <class ELEM> bool List<ELEM>::isEmpty( ) const // return TRUE if list is empty { return numinlist == 0; } bool List<ELEM>::isInList( ) const // TRUE if curr is within list { return (curr >= 0) && (curr < numinlist); } bool List<ELEM>::find(int val) { // find value (starting at curr) while (isInList( )) // stop if reach end if (key(currValue( )) == val) return TRUE; // found it else next( ); return FALSE; // not found } E.G.M. Petrakis lists
Array Implementation (2) 1 11 5 26 list 10 12 8 9 13 nodes NULL E.G.M. Petrakis lists
31 3 14 37 6 5 12 List 1 17 26 List 2 19 32 List 3 1 18 13 11 4 15 List 4 E.G.M. Petrakis lists
List 4 List 2 List 3 List 1 E.G.M. Petrakis lists 1 26 2 11 10 3 5 16 2 11 10 3 5 16 4 25 17 6 13 7 8 19 9 14 22 12 31 15 37 24 18 32 20 21 23 List 4 List 2 List 3 List 1 E.G.M. Petrakis lists
template <class ELEM> class list { // array based list class private: int msize // maximum size of list int numinlist // actual number of ELEMs int curr; // position of “current” int avail; // next available position ELEM* listarray; // array holding ELEMs int* listarray_next; // array holding pointers to next ELEMs int get_node( ); // get position of available node void free_node( ); // return node in array void insert(int, const ELEM&); // insert after the node pointed by p void delete(int, ELEM*); // delete after the node pointed by p public: list (const int=LIST_SIZE); // constructor ~list( ); // destructor void clear( ); // remove all ELEMs from list void insert(const ELEM&); // insert ELEM at current position void append(const ELEM&); // insert ELEM at tail of list ELEM remove( ); // remove and return current ELEM void setFirst( ); // set curr to first position; void prev( ); // move curr to previous position; void next( ); // move curr to next position; int length( ) const; // return current length of list }; E.G.M. Petrakis lists
template <class ELEM> List<ELEM>::list(int sz) { // constructor: initialize msize = sz; numinlist = 0; curr = 0; listarray = new Elem[sz]; listarray_next = new int[sz]; avail = 0; // the first available element for (i=0; i < msize; i++) listarray_next[i] = i+1; // each elem points to its successor listarray_next[msize-1] = nothing; // the last elem has no next } List<ELEM>::~list( ) // destructor: return array space { delete [ ] listarray; delete [ ] listarray_next; E.G.M. Petrakis lists
template <class ELEM> int list<ELEM>::get_node( ) { //get next available node if (avail == nothing) // from stack error(‘list overflow’) else { int pos = avail; avail = listarray_next[avail]; return pos; } template <class ELEM> // make node available void list<ELEM>::free_node (int p) { listarray_next[p] = avail; // push node back to stack avail =p; E.G.M. Petrakis lists
template <class ELEM> // insert after node pointed to by “p” void list<ELEM> ::insert(int p, const ELEM& x) { if (p < 0 || p >= msize) error (‘void insertion’) else { int q = get_node( ); listarray[q] = x; listarray_next[q] = listarray_next[p]; listarray_next[p] = q; } template <class ELEM> void list<ELEM> ::delete(int p; ELEM* x) { if ( p > 0 || p >= msize) // deletes elem after elem error (‘void deletion’); // pointed to by “p” int q = listarray_next[p]; *x = listarray[q]; listarray_next[p] = listarray_next[q]; free_node(q); E.G.M. Petrakis lists
Dynamic Memory The node class Allocates memory for new elements as needed Each node is a distinct object The node class template <class ELEM> class link { // a linked-list node public: ELEM element // node value link *next; // pointer to next node link(const ELEM & val, link *nextval = NULL); {element = val; next = nextval;} link(link *nextval = NULL) {next = nextval;} ~link( ) { } } E.G.M. Petrakis lists
template <class Elem> class List { // Linked list class private: Link<Elem>* head; // pointer to list header Link<Elem>* tail; // pointer to last Elem in list Link<Elem>* curr; // position of "current" Elem public: List( ); // constructor ~List( ); // destructor void clear( ); // remove all Elems from list void insert(const Elem); // insert Elem after current position void append(const Elem); // insert Elem at tail of list Elem remove( ); // remove and return after current Elem void setFirst( ); // set curr to first position void prev( ); // move curr to previous position void next( ); // move curr to next position int length( ) const; // return current length of list void setPos(int); // set curr to specified position void setValue(const Elem); // set current Elem's value Elem currValue( ) const; // return current Elem's value bool isEmpty( ) const; // return TRUE if list is empty bool isInList( ) const; // TRUE if curr is within list bool find(Elem); // find value (from current position) }; E.G.M. Petrakis lists
template <class Elem> List<Elem>::List( ) // constructor { head = new Link<Elem>; tail = head; curr = head; } // initialize List<Elem>::~List( ) { // destructor while(head != NULL) { // return link nodes to free store curr = head; head = headnext; delete curr; } void List<Elem>::clear( ) { // remove all Elems from list while (headnext != NULL) { // return link nodes to free store curr = headnext; // keeps header node !! headnext = currnext; // otherwise, similar to ~List( ) tail = head; // reinitialize E.G.M. Petrakis lists
template <class Elem> void List<Elem>::insert(const Elem item) // insert Elem after current { assert(curr != NULL); // must be pointing to list Elem currnext = new Link<Elem>(item, currnext); if (tail == curr) // appended new Elem tail = currnext; } void List<Elem>::append(const Elem item) // insert Elem at tail of list { tail = tailnext = new Link<Elem>(item, NULL); } Elem List<Elem>::remove( ) { // remove elem after current assert(isInList( )); // must be valid position in list Elem temp = currnextelement; // remember value Link<Elem>* ltemp = currnext; // remember link node currnext = ltempnext; // remove from list if (tail == ltemp) tail = curr; // removed last Elem: set tail delete ltemp; // send link to free store return temp; // return value removed E.G.M. Petrakis lists
template <class Elem> void List<Elem>::setFirst( ) // set curr to first position { curr = head; } void List <Elem>::next( ) // move curr to next position { if (curr != NULL) curr = currnext; } void List <Elem>::prev( ) { // move curr to previous pos Link<Elem>* temp = head; if ((curr == NULL) || (curr == head)) // no previous Elem { curr = NULL; return; } // so just return while ((temp!=NULL) && (tempnext != curr)) temp=tempnext; curr = temp; } int List <Elem>::length( ) const { // return current length of list int cnt = 0; for (Link<Elem>* temp = headnext; temp != NULL; temp = tempnext) cnt++; // count Elems and return cnt; E.G.M. Petrakis lists
template <class Elem> bool List <Elem>::find(Elem val) { // find value (starting at curr) while (isInList( )) if (key(currnextelement) == val) return TRUE; else curr = currnext; return FALSE; // not found } void List<Elem>::setPos(int pos) { // set curr to position curr = head; for (int i = 0; (curr != NULL) && (i < pos) i++) curr = currnext; void List<Elem>::setValue(const Elem val) { // set current Elem's value assert(isInList()); currnextelement = val; E.G.M. Petrakis lists
template <class Elem> Elem List<Elem>::currValue const // return value of current Elem { assert(isInList( )); return currnextelement; } bool List<Elem>::isEmpty( ) const // return TRUE if list is empty { return headnext == NULL; } bool List<Elem>::isInList( ) const // TRUE if curr is within list { return (curr != NULL) && (currnext != NULL); } E.G.M. Petrakis lists
Comparison Array-Based Lists: Linked Lists: insertion and deletion are (n) prev and direct access are (1) fixed space allocated in advance space reorganization if the array is full faster in most cases Linked Lists: insertion and deletion are (1) prev and direct access are (n) space grows with number of elements every element requires overhead slower E.G.M. Petrakis lists
Doubly Linked List Allows for direct access to both next and previous elements of the current pointer insert (delete) operations update both “next” and “prev” pointers easy implementation curr next = new (item, currnext, curr); if (currnext != NULL) currnextprev = currnext E.G.M. Petrakis lists
Insertion in Doubly Linked List current E.G.M. Petrakis lists
Deletion in Doubly Linked List current current E.G.M. Petrakis lists
Circular Linked Lists The next pointer of the last element points to the first element E.G.M. Petrakis lists