1 joe meehean. conceptual picture n items chained together using pointers pointed to by head...

62
Linked List 1 Joe Meehean

Upload: shannon-robertson

Post on 29-Dec-2015

216 views

Category:

Documents


0 download

TRANSCRIPT

CS242 Data Structures II

Linked List1Joe Meehean

Linked ListConceptual Picture N itemschained together using pointerspointed to by head variableAdvantageallows list to grow indefinitely without copyingconstant time inserts and removesjust (un)hook into/from chainitem 1phead:item N2List NodePrivate nested classnested class: class defined within a classprivate nested: not visible outside outer classMember variablespublic:T data_;Node *next_;ConstructorNode( const T& data = T(), Node* n = NULL)item 13Connecting List NodesNode* phead;phead:phead = new Node(ant);antphead:phead->next = new Node(bat);antphead:bat4DISCUSSIONBREAK!!!Given phead and a pointer nWhat expression gets node containing:antbatcat

antbatn:cat5phead:Given head and a pointer nWhat expression gets node containing:ant => *pheadbat => *(phead->next), *ncat => *(phead->next->next), *(n->next)

DISCUSSIONBREAK!!!antphead:batn:cat6Inserting Nodesantbatn:catjartmp:7phead:Inserting Nodesantbatn:catjartmp:8phead:Inserting Nodesantbatn:catjartmp:9phead:Removing Nodesantphead:batcatjarn:10Removing Nodesantbatcatjarn:11phead:Removing Nodesantbatcatjarn:12phead:Using Nodes to make a ListLCLinkedListMember Variablesint numItems;Node* phead;Methodssame ADT as ArrayListalso has push_front, pop_frontsame public methods13push_frontantphead:batcat14tmp:push_frontantphead:batcat15tmp:push_frontantphead:batcat16tmp:push_front void push_front(const T& newItem){ Node* tmp = new Node(newItem); tmp->next = phead; phead = tmp; numItems++;}17push_backantphead:batcat18tmp:push_backantphead:batcat19tmp:push_back void push_back(const T& newItem){ // list is empty (special case) if( phead == NULL ){ phead = new Node(newItem); }else{ // find the end of the list Node* cursor = phead; while(cursor->next != NULL){ cursor = cursor->next; } // add the item cursor->next = new Node(newItem); // increment the count numItems++;}}20Questions?21Recall: push_front void push_front(const T& newItem){ Node* tmp = new Node(newItem); tmp->next = phead; phead = tmp; numItems++;}22Recall: push_back void push_back(const T& newItem){ // list is empty (special case) if( phead == NULL ){ phead = new Node(newItem); }else{ // find the end of the list Node* cursor = phead; while(cursor->next != NULL){ cursor = cursor->next; } // add the item cursor->next = new Node(newItem); // increment the count numItems++;}}23Header NodeHeaderphead:antbatEliminates special 1st node case for add and removeCreate header at initializationDont count in sizeIgnore for contains24push_back (with header)void push_back(const T& newItem){ // find the end of the list Node* cursor = phead; while(cursor->next != NULL){ cursor = cursor->next; } // add the item cursor->next = new Node(newItem); // increment the count numItems++;}25Can you modify LCLinkedList to push_back() in O(1)?Hint: You can add member variables

26DISCUSSIONBREAK!!!Tail PointerHeaderphead:antbatpush_back now constant timebut, we must update tail pointer when adding to end27ptail:Tail PointerHeaderphead:tail pointer points at header if list is empty28ptail:pop_back()Headerphead:antbat29ptail:pop_back()Headerphead:antbat30ptail:pop_back (with header and tail pointer)void pop_back(){ if( phead != ptail ){ // find the node just before ptail Node* cursor = phead; while(cursor->next != ptail){ cursor = cursor->next; } // remove the node delete cursor->next; cursor->next = NULL; ptail = cursor; // decrement the count numItems--;}}31pop_back()Headerphead:antbatTail pointer close to the right positionStill must iterate over nearly entire listCan we make remove at end O(1)?32ptail:Can you modify LCLinkedList to pop_back() in O(1)?Hint: You can modify the structure of the list

33DISCUSSIONBREAK!!!Doubly Linked ListHeaderphead:batantNodeMember variablespublic:T data;Node *next;Node *prev34ptail:Tail NodeHeaderphead:batTailTail noderemoves special cases just like header nodetail and header node called sentinels35ptail:pop_back()Headerphead:batTail36ptail:pop_back()Headerphead:batTail37ptail:pop_back()Headerphead:batTail38ptail:pop_back()Headerphead:batTail39ptail:pop_back (doubly linked with sentinels)void pop_back(){ if( phead->next != ptail ){ ptail->prev = ptail->prev->prev; delete ptail->prev->next; ptail->prev->next = ptail; // decrement the count numItems--; }}40Linked Lists vs Array ListsSpacelinked needs two extra pointers per entrylinked needs two extra nodesarray may be up to N/2-1 too largearray may be way too big if some elements removedarray better small data items (e.g., ints)linked way better for big items (e.g., classes)too close to call for medium items (e.g., 3 ints)

41Linked Lists vs Array ListsTime

MethodArray ListLinked Listadd to endO(N)avg: O(1)O(1)add to frontO(N)O(1)remove at endO(1)O(1)remove at frontO(N)O(1)get at nO(1)O(N)42Linked Lists vs Array ListsEase implementationfairly closelinked list has more special cases and work-arounds for special cases

43Questions?44Expanding List FunctionalityWhat if we want to remove an item from the middle of a linked list?remove at itraverse list from beginning until we reach ifix up the pointersO(N)45Expanding List FunctionalityWhat if we were already moving through the list?e.g., remove all even numbersif we did this internally (inside the list class),we would have a pointer to the node to removeO(1)46Linked List IteratorsLCList::IteratorPublic nested class in LCListMember dataNode * currNode;FriendsLCList47Linked List IteratorIterator::Iterator() : currNode(NULL){}Iterator::Iterator(Node* pNode) : currNode(pNode){}

void Iterator::operator ++(){ currNode = currNode->next;}void Iterator::operator -(){ currNode = currNode->prev;}T& Iterator::operator *(){ return currNode->data;}48Linked List IteratorIterator LCList::begin(){ return Iterator(phead->next);}Iterator LCList::end(){ return Iterator(ptail);}49remove(Iterator)Headphead:batTail50ptail:catantratiter:remove(Iterator)Headphead:batTail51ptail:catantratiter:remove(Iterator)Headphead:batTail52ptail:catantratiter:remove(Iterator)Headphead:batTail53ptail:catantratiter:Linked List IteratorIterator LCList::remove(Iterator& itr){ Node* pNode = itr.currNode; // make a new iterator to return back Iterator retVal = (pNode->next); // update the pointers pNode->prev->next = pNode->next; pNode->next->prev = pNode->prev; // clean up the memory delete pNode; // decrement the count nrItems--; return retVal;}54insert(Iterator)Headphead:batTail55ptail:catantratiter:insert(Iterator)Headphead:batTail56ptail:catantratiter:insert(Iterator)Headphead:batTail57ptail:catantratiter:insert(Iterator)Headphead:batTail58ptail:catantratiter:Linked List Iteratorvoid LCList::insert(Iterator& iter, const T& t){ // extract the node from the iterator Node* pNode = iter.currNode // make a new node to store the item Node* newNode = new Node(t, pNode->prev, pNode); // fix up the pointers pNode->prev->next = newNode; pNode->prev = newNode; // increment the count nrItems++;}59Linked List IteratorsPotential errors in remove and insertuninitialized iteratorsiterators for other listsFixescheck iterators current node for NULLadd a new member value to Iterator:List* myList60Linked Lists vs Array ListsTime for iterative work

MethodArray ListLinked Listremove at n(with iterator)O(N)O(1)insert at n(with iterator)O(N)O(1)get at n(with iterator)O(1)O(1)get at n(without an iterator)O(1)O(N)61Questions?62