list implementations
play

List Implementations Mark Redekopp David Kempe Sandra Batista 2 - PowerPoint PPT Presentation

1 CSCI 104 List Implementations Mark Redekopp David Kempe Sandra Batista 2 Lists Ordered collection of items, which may contain duplicate values, usually accessed based on their position (index) Ordered = Each item has an index and


  1. 1 CSCI 104 List Implementations Mark Redekopp David Kempe Sandra Batista

  2. 2 Lists • Ordered collection of items, which may contain duplicate values, usually accessed based on their position (index) – Ordered = Each item has an index and there is a front and back (start and end) – Duplicates allowed (i.e. in a list of integers, the value 0 could appear multiple times) – Accessed based on their position ( list[0], list[1], etc. ) • What are the operations you perform on a list? list[0] list[1] list[2]

  3. 3 List Operations Operation Description Input(s) Output(s) insert Add a new value at a particular Index : int location shifting others back Value remove Remove value at the given location Index : int Value at location get / at Get value at given location Index : int Value at location set Changes the value at a given location Index : int Value empty Returns true if there are no values in bool the list size Returns the number of values in the int list push_back / Add a new value to the end of the list Value append find Return the location of a given value Value Int : Index

  4. 4 Implementation Options Linked Implementations Array-based Implementations • • Allocate each item separately Allocate a block of memory to hold many items • Random access (get the i-th • element) is O(___) Random access (get the i-th element) is O(___) • Adding new items never requires • others to move Adding new items may require others to shift positions • Memory overhead due to • pointers Memory overhead due to potentially larger block of memory with unused locations 0x148 0x148 0x1c0 head 0 1 2 3 4 5 6 7 8 9 10 11 0x0 3 9 0x1c0 data 30 51 52 53 54 10 21 NULL val next val next

  5. 5 Implementation Options Singly-Linked List • Singly-Linked List head size 3 0x148 tail 0x168 – With or without tail 0x148 0x1c0 0x168 0x0 3 9 2 0x1c0 0x168 pointer (Null) val next val next val next • Doubly-Linked List Doubly-Linked List head tail 0x148 0x168 size 3 – With or without tail 0x1c0 0x148 pointer 0x0 0x0 3 9 0x1c0 0x148 (Null) (Null) • Array-based List val next val next prev prev Array-based List size data 7 12 0x200 cap 0 1 2 3 4 5 6 7 8 9 10 11 0x200 30 51 52 53 54 10 21

  6. 6 LINKED IMPLEMENTATIONS

  7. 7 Array Problems • Once allocated an array cannot grow or shrink • If we don't know how many items will be added we could just allocate an array larger than we need but… – We might waste space – What if we end up needing more…would need to allocate a new array and copy items • Arrays can't grow with the needs of the client 21 append(21) => 0 1 2 3 4 5 Old, full array 30 51 52 53 54 10 0 1 2 3 4 5 6 7 8 9 10 11 Allocate new array 0 1 2 3 4 5 6 7 8 9 10 11 Copy over items 30 51 52 53 54 10 0 1 2 3 4 5 6 7 8 9 10 11 Add new item 30 51 52 53 54 10 21

  8. 8 Motivation for Linked Lists • Can we create a list implementation that can easily grow or shrink based on the number of items currently in the list • Observation: Arrays are allocated and deallocated in LARGE chunks – It would be great if we could allocate/deallocate at a finer granularity • Linked lists take the approach of allocating in small chunks (usually enough memory to hold one item) Bulk Item Single Item (i.e. array) (i.e. linked list)

  9. 9 Note • The basics of linked list implementations was taught in CS 103 – We assume that you already have basic exposure and practice using a class to implement a linked list – We will highlight some of the more important concepts

  10. 10 Linked List Item blueprint: int Item* • Use structures/classes and pointers #include<iostream> val next using namespace std; to make ‘ linked ’ data structures struct Item { • A linked list is… int val; Item* next; – Arbitrarily sized collection of values }; – Can add any number of new values class List void List::push_back(int v) { via dynamic memory allocation (see { public: Item i; i.val=v; side inset of push_back) List(); i.next=NULL; ~List(); – Supports typical List ADT operations: if(head == NULL){ void push_back( int v); head = &i ; • ... Insert } private: • else { ... } Get Item* head_; } • Remove }; • Size ( Should we keep a size data member? ) • Empty 0x148 0x1c0 0x168 head 0x148 • 0x0 Can define a List class to encapsulate 3 9 2 0x1c0 0x168 (Null) the head pointer and operations on val next val next val next the list Rule of thumb : Still use ‘ structs ’ for objects that are purely collections of data and don’t really have operations associated with them. Use ‘classes’ when data does have associated functions/methods.

  11. 11 Don't Need Classes #include<iostream> • Notice the class on the using namespace std; Item blueprint: struct Item { int Item* previous slide had only 1 data int val; val next Item* next; member (the head pointer) }; // Function prototypes void append(Item*& head, int v); • We don't have to use classes… bool empty(Item* head); int size(Item* head); – The class just acts as a wrapper int main() around the head pointer and the { operations Item* head1 = NULL; Item* head2 = NULL; – So while a class is probably the int size1 = size( head1 ); correct way to go in terms of bool empty2 = empty( head2 ); append(head1, 4); organizing your code, for today we } can show you a less modular, class List: procedural approach head_ • Define functions for each 0x0 operation and pass it the head Rule of thumb : Still use ‘ structs ’ for objects that are pointer as an argument purely collections of data and don’t really have operations associated with them. Use ‘classes’ when data does have associated functions/methods.

  12. 12 Linked List Implementation #include<iostream> struct Item { • To maintain a linked list you need only int val; Item* next; keep one data value: head }; – Like a train engine, we can attach any void append(Item*& head, int v); number of 'cars' to the engine int main() – The engine looks different than all the { others Item* head1 = NULL; Item* head2 = NULL; • In our linked list it's just a single pointer to an Item } • All the cars are Item structs • Each car has a hitch for a following car (i.e. next pointer) head1 0x0 NULL Engine = Each car = 0x0 NULL "head" "Item" head2

  13. 13 Append #include<iostream> • Adding an item (train car) to the using namespace std; struct Item { int val; back can be split into 2 cases: Item* next; }; – Case 1: Attaching the car to the void append(Item* & head, int v) engine (i.e. the list is empty and we { have to change the head pointer) if(head == NULL){ head = new Item; • Changing the head pointer is a special case head->val = v; head->next = NULL; } since we must ensure that change else {...} propagates to the caller } – Case 2: Attaching the car to another int main() car (i.e. the list has other Items { Item* head1 = NULL; already) and so we update the next Item* head2 = NULL; append(head1, 3); pointer of an Item } head1 0x148 0x0 0x148 3 NULL val next

  14. 14 Linked List #include<iostream> • Adding an item (train car) to the using namespace std; struct Item { back can be split into 2 cases: int val; Item* next; }; – Attaching the car to the engine (i.e. the list is empty and we have to void append(Item*& head, int v) { change the head pointer) if(head == NULL){ head = new Item; – Attaching the car to another car (i.e. head->val = v; head->next = NULL; } the list has other Items already) and else {...} so we update the next pointer of an } Item int main() { Item* head1 = NULL; Item* head2 = NULL; append(head1,3); append(head1,9); } head 0x148 0x148 0x1c0 0x0 3 9 0x1c0 NULL NULL val next val next

  15. 15 Linked List #include<iostream> • Adding an item (train car) to the using namespace std; struct Item { back can be split into 2 cases: int val; Item* next; – Attaching the car to the engine (i.e. }; the list is empty and we have to void append(Item*& head, int v) { change the head pointer) if(head == NULL){ head = new Item; – Attaching the car to another car (i.e. head->val = v; head->next = NULL; } the list has other Items already) and else {...} so we update the next pointer of an } Item int main() { Item* head1 = NULL; Item* head2 = NULL; append(head1, 3); append(head1, 9); append(head1, 2); } head 0x148 0x148 0x1c0 0x168 0x0 9 3 2 0x1c0 0x168 (Null) val next val next val next

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend