280 likes | 331 Vues
Chapter 3 – Lists. A list is just what the name implies, a finite, ordered sequence of items. Order indicates each item has a position. A list of size 0 is the empty list. The first element is element 1 and the last element is element N in a list of size N.
E N D
Chapter 3 – Lists • A list is just what the name implies, a finite, ordered sequence of items. • Order indicates each item has a position. • A list of size 0 is the empty list. • The first element is element 1 and the last element is element N in a list of size N. • Operations can include: insert, remove, findKth, find, next, previous. • Must consider special cases, no previous, no next, not found …
Generic List Functions void clear(); // reinitialize the list bool insert(const Elem &); //insert an item into the list before the current item. Return false if the list is full. bool append(const Elem &); //insert an item after the last. bool remove(Elem &); //remove the item at the current. Return false if current is empty. void setStart(); //set current to the beginning. void setEnd(); // set current to the last. void prev(); // set current to the previous item. No change if current is at the first. void next(); // set current to the next item. No change if current is at the end.
More List Functions int leftLength(); // the size of the list before the current int rightLength(); // the size of the list after and including the current. bool setPos(int); // set current to the position indicated by the argument. Return false if there are not enough in the list. bool getValue (Elem &); // return the value of the current item in the argument. Return false if there is no current item. void print(); // print out the items in the list.
Array Implementation • Can use an array to implement a list. • Fixed size. • FindKth very fast. • Insert and remove will cause lots of movement. • Find is linear unless the list is ordered.
Array Based List Implementation template <class E> class List{ private: int maxSize; int listSize; int curr; Elem * listArray; public: methods discussed };
Some Array Based List Functions • Constructor List(int size=DEFAULTSIZE) { maxSize=size; listSize=curr=0; listArray=new Elem[size]; } • void setStart() {curr=0}; • bool append(const Elem & item) { if (listSize==maxSize) return false; listArray[listSize++]=item; }
Linked List • Allows dynamic memory. • Each node has a link to the next item in the list. (extra memory). • Last item’s next points to NULL. • Insert and remove take constant time. • FindKth is now linear.
Programming Trick • To insert or remove at the beginning is a special case (must change the head pointer). • Instead, create a “header node” that contains no data. • This node will never be deleted. • The head pointer will always point to the header node. • Created in the constructor. • Called node 0.
Iterator and Container Classes • A container class is designed to hold collections of objects (list, stack, queue, tree, …). • This class provides services such as insertion, deletion, searching, sorting, find,… • It is common to associate iterator objects with container classes. • Being friends is appropriate.
Iterator Classes • An iterator is an object that returns an item of a container. This is much like using pointers. • We do not want the user to get indiscriminate use of a pointer (then they can change the data in a private area). • Use iterator classes to handle these pointers for the user. • This way, the user can keep “pointers” to multiple locations in a container.
Iterators (cont.) • You can think of an iterator as a bookmark within the container. • Easily allows multiple bookmarks in one container. • The container class can use iterator objects. • Package both classes in same .h and .cxx files. • Need to give an incomplete class declaration since both classes need both classes.
List Implementation • Now a list should have 3 classes associated with it. • ListNode – Holds the data of 1 element in the list (many times implemented as a struct) • List – Holds a pointer to the first item. • ListItr – keeps track of a position in the List. • Package them all together, friends will be o.k.
Doubly Linked List • One of the operations was to give the previous. This is fine and can be done with one extra pointer as long as we will just use the previous function once in a row. • To allow unlimited backing up, need a previous pointer in each node. • Uses more memory, but will not be significantly slower. Now no need for a separate previous pointer for insertion and deletion.
Circular Linked List • Instead of having the last node’s next point to NULL, have it point to the first. • This is useful in circular applications, when the first follows the last.
Polynomial Application • Many high level polynomials have many terms with a 0 coefficient. • Would need to store them if using an array. • Use a linked list to not take memory for items with a 0 coefficient.
Big Numbers • To allow for arbitrary large numbers, use a linked list where each holds one digit. • This is good conceptually, but for efficiency, we can use an int to hold several digits per node. • Similarly, we can use a linked list for a string of arbitrary length.
MultiLists • Sometimes we have one set of data, but want to process it in different orders. • DMV info, may want to go in name order or driver’s license order, or in tag order. • Rather than having the data duplicated several times for several lists, use multiple pointers. • Having duplicated data makes the update process difficult and error prone. • Each pointer is the next for a particular list. • Nextname, nextlic, nexttag • Now insertions are really inserting into 3 lists.
Freelists • The system new and delete are very slow. • When your program does a free, do not give it back to the system. • Instead, keep it around in another list to be used to give back the next time the program does a new. • If your freelist is empty, then the class will actually need to do a new. • Can accomplish this by overloading the system new and free operations. (Can still access the system new and free).
Freelist Implementation Class ListNode{ public: ELEM element; ListNode * next; static Listnode * freelist; ListNode(const ELEM & elemval, link * nextval=NULL) {element=elemval; next=nextval;} ListNode(ListNode * nextval=NULL) {next=nextval;} ~ListNode() {} void * operator new(size_t); void operator delete(void *);}; ListNode * ListNode::freelist=NULL; void * ListNode::operator new(size_t){ if (freelist==NULL) return ::new ListNode; ListNode * temp=freelist; freelist=freelist->next; return temp; } void ListNode::operator delete(void* ptr) { ((ListNode *) ptr)->next=freelist; freelist = (ListNode*) ptr;}
Array Implementation • Can have array based lists or • Array based linked lists. • Array based lists are simple but have a lot of data movement for insertions and deletions. • Array based linked list will have essentially 2 linked lists in one array, one for the free items and one for the actual data.
Array Linked Lists • Use and extra field for a next pointer. • This pointer will be an integer that points to a position in the array (via a subscript). • NULL will need to be –1 rather than 0. • Need a head pointer to tell which item is first.
Array Linked List Example Head is 3 Free is 4
Array Linked List Initialization • The initial linked list will have Head = NULL = -1 • The initial free list will be 0 and Next[i]=i+1 and Next[last]=NULL • To accomplish a new, we remove the front of the free list {newptr=free; free=next[free];} • To accomplish a remove we add the node to the front of the free list {next[deleted]=free; free=deleted;} • Need to use subscripts instead of pointers (->)
Stacks • LIFO: Last In, First Out. • Restricted form of a list. • Insert only at the front. • Remove from the front. • Notation • Insert: PUSH • Remove: POP • The accessible element is called TOP.
Queues • FIFO: First In, First Out. • Restricted form of a list. • Insert at one end. • Remove from the other end. • Notation • Insert: Enqueue. • Delete: Dequeue. • First Element: FRONT. • Last Element: REAR.
Queue Implementations • Linked Queue • Very easy and intuititive. • Always add at the rear (trivial with a rear pointer). • Always delete at the front (trivial with pointer to front). • Array based Queue • Have an int to tell where the rear is (start at 0, increment when add). • Have int to tell where front is (start at 0, increment when delete). • Front chases the Rear. • No data movement. • May get to end and think queue is full when there are empty spots. • Make circular. When Front and Rear get to end of array reset them to the beginning of the array. • If rear “passes” front during insertion then full. • If front “passes” rear during a deletion, then empty.