1 / 26

CS162 - Topic #8

CS162 - Topic #8. Lecture: Dynamic Data Structures Walk through the examples assigned at the end of last class inserting at the end of a linked list removing at the beginning of a linked list Stacks and Queues Programming Assignment Questions. CS162 - Inserting at End.

madelynd
Download Presentation

CS162 - Topic #8

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. CS162 - Topic #8 • Lecture: Dynamic Data Structures • Walk through the examples assigned at the end of last class • inserting at the end of a linked list • removing at the beginning of a linked list • Stacks and Queues • Programming Assignment Questions

  2. CS162 - Inserting at End • Add a node at the end of a linked list. • What is wrong with the following. Correct it in class: node * current = head; while (current != NULL) { current = current->next; } current= new node; current->data = new video; current->data = data_to_be_stored; } LOOK AT THE BOLD/ITALICS FOR HINTS OF WHAT IS WRONG!

  3. CS162 - Inserting at End • We need a temporary pointer because if we use the head pointer • we will lose the original head of the list and therefore all of our data • If our loop’s stopping condition is if current is not null -- then what we are saying is loop until current IS null • well, if current is null, then dereferencing current will give us a segmentation fault • and, we will NOT be pointing to the last node!

  4. CS162 - Inserting at End • Instead, think about the “before” and “after” pointer diagrams: Before ••• head 1ST NTH After ••• head 1ST new node NTH current

  5. CS162 - Inserting at End • So, we want to loop until current->next is not NULL! • But, to do that, we must make sure current isn’t NULL • This is because if the list is empty, current will be null and we’ll get a fault (or should) by dereferencing the pointer if (current) while (current->next != NULL) { current = current->next; }

  6. CS162 - Inserting at End • Next, we need to connect up the nodes • having the last node point to this new node current->next = new node; • then, traverse to this new node: current = current->next; current->data = new video; • and, set the next pointer of this new last node to null: current->next = NULL;

  7. CS162 - Inserting at End • Lastly, in our first example for today, it was inappropriate to just copy over the pointers to our data • we allocated memory for a video and then immediately lost that memory with the following: current->data = new video; current->data = data_to_be_stored; • the correct approach is to allocate the memory for the data members of the video and physically copy each and every one

  8. CS162 - Removing at Beg. • Now let’s look at the code to remove at node at the beginning of a linear linked list. • Remember when doing this, we need to deallocate all dynamically allocated memory associated with the node. • Will we need a temporary pointer? • Why or why not...

  9. CS162 - Removing at Beg. • What is wrong with the following? node * current = head->next; delete head; head = current; • everything? (just about!)

  10. CS162 - Removing at Beg. • First, don’t dereference the head pointer before making sure head is not NULL if (head) { node * current = head->next; • If head is NULL, then there is nothing to remove! • Next, we must deallocate all dynamic memory: delete [] head->data->title; delete head->data; delete head; head = current; //this was correct....

  11. CS162 - Removing at End • Now take what you’ve learned and write the code to remove a node from the end of a linear linked list • What is wrong with: (lots!) node * current = head; while (current != NULL) { current = current->next; } delete [] current->data->title; delete current->data; delete current; }

  12. CS162 - Removing at End • Look at the stopping condition • if current is null when the loop ends, how can we dereference current? It isn’t pointing to anything • therefore, we’ve gone too far again node * current = head; if (!head) return 0; //failure mode while (current->next != NULL) { current = current->next; } • is there anything else wrong? (yes)

  13. CS162 - Removing at End • So, the deleting is fine.... delete [] current->data->title; delete current->data; delete current; • but, doesn’t the previous node to this still point to this deallocated node? • when we retraverse the list -- we will still come to this node and access the memory (as if it was still attached).

  14. CS162 - Removing at End • When removing the last node, we need to reset the new last node’s next pointer to NULL • but, to do that, we must keep a pointer to the previous node • because we do not want to “retraverse” the list to find the previous node • therefore, we will use an additional pointer • (we will call it “previous”)

  15. CS162 - Removing at End • Taking this into account: node * current= head; node * previous = NULL; if (!head) return 0; while (current->next) { previous = current; current = current->next; } delete [] current->data->title; delete current->data; delete current; previous->next = NULL; //oops... } Can anyone see the remaining problem?

  16. CS162 - Removing at End • Always think about what special cases need to be taken into account. • What if... • there is only ONE item in the list? • previous->next won’t be accessing the deallocated node (previous will be NULL) • we would need to reset head to NULL, after deallocating the one and only node

  17. CS162 - Removing at End • Taking this into account: ••• if (!previous) //only 1 node head = NULL; else previous->next = NULL; } Now, put this all together as an exercise

  18. CS162 - Stacks • We have talked about lists of data much of the term • One common use of a list is to represent a stack abstraction • Stacks allow us to add data and remove data at only one end (called the top) • We can push data onto the top and pop data off of the top (LIFO)

  19. CS162 - Stacks • Then, our stack class could be: class stack { public: stack(); ~stack(); int push (const video &); int pop (video &); int isempty(); private: node * top; //if implemented with a LLL };

  20. CS162 - Stacks • Implementing push and pop with a linear linked list data structure • represent very simple insert and remove algorithms • in fact, push is the same as adding at the beginning of a LLL • and, pop is the same as removing at the beginning of a LLL • why wouldn’t we add/remove at the end (or tail) instead?

  21. CS162 - Stacks • why wouldn’t we add/remove at the end (or tail) instead? • pushing at the tail would be just as easy and efficient as pushing at the head iff we kept a tail pointer. • but, popping at the tail would require that we traverse to the (tail-1) node...regardless of whether or not there was a tail pointer. • a doubly linked list is not the answer

  22. CS162 - Queues • Another common use of a list is to represent a queue abstraction • Queues allow us to add data at one end (the rear) and remove data at the other end (at the front) • We can enqueue data at the rear and dequeue data at the front (FIFO)

  23. CS162 - Queues • Then, our queue class could be: class queue { public: queue(); ~queue(); int enqueue (const video &); int dequeue (video &); int isempty(); private: node * rear; //if implemented with a LLL node * front; };

  24. CS162 - Queues • Implementing enqueue and dequeue with a linear linked list data structure • are also simple • but, should the “rear” pointer point to the first or the last node? And, should the “front” pointer point to the first or the last node? • draw the pointer diagrams for either way and decide which would traverse less...

  25. CS162 - Queues • enqueue should add at the rear - the tail • dequeue should remove at the front - the head • Why? • enqueuing at the front or rear is equally easy and efficient • but, dequeuing at the rear requires that we traverse to the “last-1” node (but a doubly linked list would be overkill). Luckily, dequeuing at the front is simple and efficient

  26. CS162 - For Next Time • Practice Linked lists • Do the following and bring to class: • implement the push, pop, enqueue, dequeue functions for the classes outlined today • implement the destructor for the stack or queue classes. Are they the same? Why? • try to insert into a LLL in sorted order......... • Any Questions on Stage #3?

More Related