1 Linked Lists Linked Lists Why should you

  • Slides: 16
Download presentation
1 Linked Lists

1 Linked Lists

Linked Lists… Why should you care? Linked Lists are used in everything from video

Linked Lists… Why should you care? Linked Lists are used in everything from video games to search engines. Any time you don’t know how many items you’ll need to store ahead of time, you use ‘em. And virtually every job interview will grill you on them. So pay attention!

3 Arrays are great… But… Arrays are great when you need to store a

3 Arrays are great… But… Arrays are great when you need to store a fixed number of items… But what if you don’t know how many items you’ll have ahead of time? Then you have to reserve enough Still requires us slots for the largest possible to know case. the size int main() { } int array[100]; … int main() {{ int //num. Items, might have*ptr; 10 items or 1 M int>>array[1000000]; cin num. Items; ptr … = newfint[num. Items]; o }} e st a w e! a t pac names[0] Andrew And what if you need to insert a new a h s names[1] Betty W item in the middle of an array? It takes Carey ahead of time! Even new/delete don’t really help! We have to move every item below the insertion spot down by one! And it’s just as slow if we want to delete an item! Yuck! names[2] names[3] names[4] names[999998] names[999999] David 1 M nearly Elaineto steps Frank add a new … item! Zappa

4 So Arrays Aren’t Always Great Hmm… Can Twe think of an approach h

4 So Arrays Aren’t Always Great Hmm… Can Twe think of an approach h e sta life” from “real works better rts huthat n t clua fixed-sized w than array? i e t h loc to ati the a the on How about the items as we of forganizing i r c he insta Scavenger Hunt? would st… Clue: The first item is by the tree Clue: The next item is by the house Clue: This is the last item! What can we think ofstore that: an Using this approach, we can arbitrary of items! allows. Tnumber you to store an ch hen arbitrary of items a es number e There’s no nfixed limit to a ite t h ch the number c makes it fast to insert ol we lu and of chests ds can have! e m aclues loa new ca toitemndin the middle th tio th a emakes n it efast to delete ch anneitemoffrom the middle es xt t. ? Clue: The next item is by the tower

5 Clue: So Arrays Aren’t Always Great Also, using this approach we can quickly

5 Clue: So Arrays Aren’t Always Great Also, using this approach we can quickly add a new item to the middle! All we have to do is add a new chest and change a few clues! For instance, let’s add a new treasure between our bananas and our toilet paper. Clue: The first item is by the tree y the p o c we o our t First e u l us c previo w chest. ne Clue: This is the last item! Clue: Thenextitemis The isbybythe thetemple house we n e Th e the to at e upd us clu new vio ur pre t to o ! t n poi ches The next item is by the tower

6 Clue: The next item is by the house So Arrays Aren’t Always Great

6 Clue: The next item is by the house So Arrays Aren’t Always Great Finally, using this approach we can quickly remove an item from the middle! All we have to do is remove the target chest and change a single clue! Clue: The first item is by the tree Clue: The next item is by the temple Clue: This is the last item! ? Clue: The next item For instance, let’s by the tower remove thisischest from the hunt…

7 A C++ Scavenger Hunt? Ok, so in our Scavenger Hunt, we had: A

7 A C++ Scavenger Hunt? Ok, so in our Scavenger Hunt, we had: A clue that leads us to our first treasure chest. Each chest then holds an item (e. g. , bananas) and a clue that leads us to the next chest. So here’s the question… can we simulate a Scavenger Hunt with a C++ data structure? Why not? Let’s see how. Clue: The first item is by the tree Clue: The next item is by the house Clue: The next item is

8 A C++ Scavenger Hunt? Well, we can use a C++ struct to represent

8 A C++ Scavenger Hunt? Well, we can use a C++ struct to represent a Chest. As we know, each Chest holds two things: A treasure – let’s use a string variable to hold our treasure, e. g. , “plunger”. The location of the next chest – let’s represent that with a pointer variable. We can now define a Chest variable for each of the items in our scavenger hunt! struct Chest { string treasure; Chest * next. Chest; }; Clue: This line basically says that The first itemeach Chest variable is by the tree holds a pointer… to another Chest variable. Clue: The next item is by the house Clue: The next item is

9 A C++ Scavenger Hunt? Well, we can use a C++ struct to represent

9 A C++ Scavenger Hunt? Well, we can use a C++ struct to represent a Chest. As we know, each Chest holds two things: A treasure – let’s use a string variable to hold our treasure, e. g. , “plunger”. struct Chest { string treasure; Chest * next. Chest; }; Clue: first OK, let’s see the C++ version The first 5000 item is byhunt the tree of next a simplified The location of the chest – let’sscavenger represent that with a pointer variable. data structure! We can now define a Chest variable for each of the items in our scavenger hunt! Clue: treasure “bananas” The next item next. Chest is by the house 3400 And we can define a pointer to point to the very first chest – our first clue! Chest *first; // pointer to our 1 st chest treasure Clue: “TP” The next item is next. Chest 1200

10 A C++ Scavenger Hunt? And update our This data structure is. We want

10 A C++ Scavenger Hunt? And update our This data structure is. We want to link up our first struct Chestchest to the called a “linked list. ” first chest so it first second chest… { points to it… string treasure; …should hold the Why? Because each int main(void) 1000 Chest * next. Chest; chest 1 treasure “toast" elementof in the first list is {}; address We”linked” call each item in the Chest *first; chest! by a pointer next. Chest chest 1, chest 2, chest 3; linked list a element. “node. ” to the next Finally, we’ll indicate that the thirdnullptr is a special C++ first = &chest 1; chest is the last in the scavenger hunt. constant that means 1020 chest 2 chest 1. treasure “toast"; “invalid pointer= value. ” “bacon" We do thistreasure by setting its next. Chest chest 1. next. Chest = &chest 2; pointer to nullptr. next. Chest chest 3 chest 2. treasure = “bacon"; chest 2. next. Chest = &chest 3; treasure “eggs" next. Chest nullptr Our= first chest 3. treasure “eggs"; chest 3. next. Chest = nullptr; pointer … 1040 } So we’ll get the address of the second chest…

11 struct Chest { string treasure; Chest * next. Chest; Normally, we don’t use

11 struct Chest { string treasure; Chest * next. Chest; Normally, we don’t use local variables }; to create our linked list. “Hey OS, can you allocate int main(void) 20 OS, bytes “Hey canfor youme? ” allocate Instead we use dynamically{ “Hey can for you me? ” allocate 20 OS, bytes Chest *first; allocated variables (and pointers!). *first, *second, *third; 20 bytes for me? ” Chest chest 1, chest 2, chest 3; Linked Lists first 5000 second 2200 treasure first = new Chest; second = new Chest; first = &chest 1; third = new Chest; chest 1. treasure = “toast"; chest 1. next. Chest = &chest 2; 5000 next. Chest third treasure 3700 next. Chest treasure chest 2. treasure = “bacon"; chest 2. next. Chest = &chest 3; 2200 chest 3. treasure = “eggs"; chest 3. next. Chest = nullptr; OS: reserved OS: “Sure –– I’ve reserved 3700 some memory for you at at location 5000. ” location 2200. ” 3700. ” next. Chest }

12 struct Chest The pointer to the top { item in the linked list

12 struct Chest The pointer to the top { item in the linked list is string treasure; traditionally called the OK, now let’s“head add cargo and link ‘em up! Chest * next. Chest; pointer. ” Given just the head }; pointer, you can reach int main(void) Again, in our last node, we’ll set every element in the list… { its next. Chest pointer to nullptr. without using your other Linked Lists head *second, *third; Chest *first, external pointers! first head 5000 second treasure "toast" head = newthat Chest; This first indicates it’s the last second new Chest; item= in the list. 5000 third = new Chest; first->treasure = "toast"; head first->next. Chest = second; head next. Chest 2200 treasure "bacon" third Oh – and let’s not forget 3700 to free our treasure next. Chest chests when we’re done with them! 3700 treasure "eggs" next. Chest second->treasure = "bacon"; second->next. Chest = third; third->treasure = "eggs"; When we encounter third->next. Chest = nullptr; a nullptr } next. Chest pointer whose delete head; value is nullptr, this delete second; indicates delete third; we’re at the end.

13 Linked Lists Ok, it’s time to start using the right Computer Science terms.

13 Linked Lists Ok, it’s time to start using the right Computer Science terms. Instead of calling them “chests", let’s call each item in the linked list a “Node”. And instead of calling the value held in a node treasure, let’s call it “value”. And, instead of calling the linking pointer next. Chest, let’s call it “next”. Finally, there’s no reason a Node only needs to hold a single value! Chest struct Node // student node struct {{ treasure; string value; int student. ID; string Chest**name; next. Chest; Node next. Chest; next; }; int phone. Number; float gpa; int main(void) {{ Node *next; Node Chest *head, *second, *third; }; head = new Chest; Node; second = new Chest; Node; third = new Chest; Node; head->value = "toast"; head->treasure = "toast"; head->next. Chest head->next = second; second->value = "bacon"; second->treasure = "bacon"; second->next. Chest second->next = third; third->value = "eggs"; third->treasure = "eggs"; third->next. Chest third->next = nullptr; delete head; delete second; delete third; }}

14 Linked Note: The Lists delete command doesn’t kill the pointer… Before we continue,

14 Linked Note: The Lists delete command doesn’t kill the pointer… Before we continue, here’s a short recap on what we’ve learned: To allocate new nodes: Node *p = new Node; Node *q = new Node; To change/access a node p’s value: p->value = “blah”; cout << p->value; To make node p link to another node that’s at address q: p->next = q; To get the address of the node after p: Node *r = p->next; To make node q a “terminal” node: nullptr q->next = nullptr; struct Nodeit kills what the { pointer points to! string value; p 8000 Node * next; value blah 8000 }; r next 4000 int main(void) { To link Node *head, *second, node *third; p… q 4000 head = new Node; second = new Node; value to node third = q. new Node; next head->value = "toast"; head->next = second; second->value = "bacon"; To free= your second->next third; nodes: delete p; third->value = "eggs"; delete q; third->next = nullptr; delete head; delete second; delete third; } 4000

15 Linked Lists Normally, we don’t create our linked list all at once in

15 Linked Lists Normally, we don’t create our linked list all at once in a single function. After all, some linked hold Welists normally millions of items! That fit! don’twouldn’t create our linked list all at once like this. Instead, we create a dedicated class (an ADT) to hold our linked list… And then add a bunch of member functions to add new items (one at a time), process the items, delete items, etc. OK, so let’s see our new class. struct Node { string value; Node * next; }; int main(void) { Node *head, *second, *third; head = new Node; second = new Node; third = new Node; head->value = "toast"; head->next = second; second->value = "bacon"; second->next = third; third->value = "eggs"; third->next = nullptr; delete head; delete second; delete third; }

16 struct Node { string value; class Linked. List Node *next; { }; public:

16 struct Node { string value; class Linked. List Node *next; { }; public: A Linked List Class! First, let’s shrink our Node definition font a bit to make room forsimplest our newtype class! In the of linked list class, the only member variable we need is a head pointer. Why? Given just the head pointer, we can follow the links to every node in the list. And since we can find all the nodes, we can also link in new ones, delete them, etc. . head 5000 value This is all our class needs to hold! "toast" 5000 next 2200 value "bacon" next 3700 value "eggs" next nullptr 2200 3700 int main(void) { Node *head, *second, *third; head = new Node; second = new Node; third = new Node; head->value = "toast"; head->next = second; second->value = Ok, "bacon"; so let’s add second->next = third; a head pointer to our class. third->value = "eggs"; third->next = nullptr; delete head; private: delete second; delete Node third; *head; 5000 } };