cs 103 unit 11
play

CS 103 Unit 11 Linked Lists Mark Redekopp 2 NULL Pointer Just - PowerPoint PPT Presentation

1 CS 103 Unit 11 Linked Lists Mark Redekopp 2 NULL Pointer Just like there was a null character in ASCII = '\0' whose value was 0 there is a NULL pointer whose value is 0 Used to represent a pointer to "nothing" NULL is


  1. 1 CS 103 Unit 11 Linked Lists Mark Redekopp

  2. 2 NULL Pointer • Just like there was a null character in ASCII = '\0' whose value was 0 there is a NULL pointer whose value is 0 – Used to represent a pointer to "nothing" – NULL is "keyword" you can use in C/C++ that is defined to be 0 – nullptr is an equivalent keyword in C++ version 11 and onward and has some advantages best explained later… • Requires special compile flags, so we may default to NULL for now • Used to indicate that the pointer does NOT point at valid data – Nothing ever lives at address 0 of memory so we can use it to mean "pointer to nothing" – Often used as an "error" return value from functions returning pointers (See http://www.cplusplus.com/reference/cstring/strchr/ ) – char* ptr = strchr("Hello", 'h') if(ptr != NULL){ … } // it's a good pointer

  3. 3 Arrays Review • #include<iostream> Fast access: Because arrays are contiguous in using namespace std; memory we can find a single value with only: int main() { – The start address int data[25]; – Which element we want (e.g. index 20) data[20] = 7; return 0; • Index 20 lives at: start_address + 20*(size_of_int) } – If we know integer element i is at location 108 do data = 100 we know where element i+1 is? 100 104 108 112 116 120 • … Can't grow (resize): Once we declare the array 45 31 21 04 98 73 Memory (either statically on the stack or dynamically on the heap) we cannot increase its size #include<iostream> using namespace std; Add one more 21 value int main() 0 1 2 3 4 5 { Old, full array 30 51 52 53 54 10 int size; cout << "Enter size: "; 0 1 2 3 4 5 6 7 8 9 10 11 cin >> size; Allocate new int *ptr = new int[size]; array 0 1 2 3 4 5 6 7 8 9 10 11 // What if we end up Copy over items // needing more than size? 30 51 52 53 54 10 } then add value

  4. 4 Analogy • Natural analogy when we have a 1. Do CS 103 lab set of items that can change is to 2. Join ACM or IEEE 3. Play Video Games create a list 4. Watch a movie – Write down what you know now 5. Exercise – Can add more items later (usually to the end of the list) – Remove (cross off) others when done with them 1. Do CS 103 lab 2. Join ACM or IEEE • Can only do this with an array if 3. Play Video Games you know max size of list ahead of 4. Watch a movie 5. Exercise time (which is sometimes fine) 6. Eat dinner

  5. 5 BFS Queue Example . . . # • The size of the BFS Queue # S # # grew and shrunk based on # . # F the data pattern • But we wasted a whole head tail LARGE array planning for the 5 worst case head tail • It'd be great to store only 5 1 9 what we need where our head tail storage can grow and shrink 5 1 9 0 2 head tail 5 1 9 0 2

  6. 6 Linked Lists • A linked list stores values in separate chunks of memory (i.e. a dynamically allocated object) • To know where the next one is, each one stores a pointer to the next • We can allocate more or delete old ones as needed so we only use memory as needed • All we do is track where the first object is (i.e. the head pointer) 0x148 0x1c0 0x168 head 0x148 0x0 3 9 2 0x1c0 0x168 (Null) val next val next val next

  7. 7 Linked Lists • What is the order of values in this linked list? • How would you insert 6 at the front of the list? • How would you remove the value 4? 0x200 head 0x0 8 (Null) 0x300 val next 0x240 4 0x3e0 0x300 val next 5 0x240 val next 0x3e0 1 0x200 val next

  8. 8 Arrays vs. Linked List #include<iostream> using namespace std; • If we have the start address of an int main() { array can we get the i-th element int data[25]; data[20] = 7; quickly? return 0; } – Yes: start-addr + i * sizeof(data) data = 100 • If we have the start (head) pointer 100 104 108 112 116 120 … to a linked list can we find the i-th 45 31 21 04 98 73 Memory element quickly? – No…Have to walk the linked list head – Items are NOT CONTIGUOUS 0x148 • Linked lists trade the ability to 0x148 0x1c0 0x168 resize (grow/shrink) for speed of 0x0 3 9 2 0x1c0 0x168 (Null) access when attempting to get a val next val next val next specific element

  9. 9 Linked List #include<iostream> • Use structures/classes and pointers using namespace std; struct Item to make linked data structures blueprint: struct Item { • int val; List int Item * Item* next; val next – Arbitrarily sized collection of }; next val values class List { – Can add any number of new values public: via dynamic memory allocation List(); ~List(); • Should always dynamically allocate void push_back( int v); ... Items in a linked list private: – Usually supports following set of Item* head; }; operations: • Append (“ push_back ”) head 0x0 • Prepend (“ push_front ”) • Remove back item (“ pop_back ”) • Remove front item (“ pop_front ”) • Find (look for particular value) 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.

  10. 10 Linked List #include<iostream> • Use structures/classes and pointers using namespace std; to make linked data structures List::List() { • Arbitrarily sized collection of values head = NULL; } • Can add any number of new values void List::push_back( int v){ via dynamic memory allocation if( head == NULL ){ // list is empty head = new Item; – Should always dynamically allocate head->val = v; head->next = NULL; Items in a linked list } else { ... } – Why? Look at the code in } List::push_back() and ask what would int main() happen if we just declare the Item on { the stack? List mylist; mylist.push_back( 3 ); • Most operations on a linked list } require a check to determine two head 0x148 potential cases: if the list IS empty 0x0 or NOT empty: – May be necessary to avoid de- 0x148 referencing a NULL pointer (i.e. 3 NULL segfault) val next – Or if the list is empty we may need to modify head

  11. 11 Linked List #include<iostream> • Use structures/classes and pointers to using namespace std; make linked data structures List::List() { • Arbitrarily sized collection of values head = NULL; } • Can add any number of new values via void List::push_back( int v){ dynamic memory allocation if(head == NULL){ head = new Item; – Should always dynamically allocate Items in head->val = v; head->next = NULL; a linked list } else { ... } // list is not empty – Why? Look at the code in List::push_back() } and ask what would happen if we just int main() declare the Item on the stack? { • List mylist; Most operations on a linked list require mylist.push_back( 3 ); mylist.push_back( 9 ); a check to determine two potential } cases: if the list IS empty or NOT head head 0x148 empty: 0x148 – May be necessary to avoid de-referencing a NULL pointer (i.e. segfault) 0x148 0x1c0 – 0x0 Or if the list is empty we may need to modify 3 9 0x1c0 NULL NULL head val next val next

  12. 12 Linked List #include<iostream> using namespace std; • List::List() Use structures/classes and pointers to { make linked data structures head = NULL; } • Arbitrarily sized collection of values void List::push_back(int v){ • if(head == NULL){ Can add any number of new values via head = new Item; dynamic memory allocation head->val = v; head->next = NULL; } – Should always dynamically allocate Items in else { ... } a linked list } – Why? Look at the code in List::push_back() int main() { and ask what would happen if we just List mylist; declare the Item on the stack? mylist.push_back(3); mylist.push_back(9); • Most operations on a linked list require mylist.push_back(2); } a check to determine two potential cases: if the list IS empty or NOT head head 0x148 empty: 0x148 – May be necessary to avoid de-referencing a NULL pointer (i.e. segfault) 0x148 0x1c0 0x168 – 0x0 Or if the list is empty we may need to modify 3 9 2 0x1c0 0x168 (Null) head val next val next val next

  13. 13 Common Linked Task/Mistake 1 • What is the C++ code to take a step from one item to the next head 0x148 • Answer: 0x148 0x1c0 – __________________________ 0x0 3 9 0x1c0 • Lesson: To move a pointer to the NULL val next val next next item use: _____________________ 0x148 0x1c0 temp temp Before taking step After taking step

  14. 14 Common Linked Task/Mistake 2 • Why do we need a temp pointer? Before taking step After taking step Why can't we just use head to take head head 0x148 1c0 a step as in: – head = head->next; 0x148 0x1c0 0x0 • Because if we change head we 3 9 0x1c0 NULL val next val next have no ___________________ __________________________ – Once we take a step we have "amnesia" and forget where we came from and can't retrace our steps • Lesson: __________________!

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