230 likes | 377 Views
Chapter 13. Pointers and Linked Lists. Nodes and Linked Lists. Linked list: A sequence of nodes in which each node is linked or connected to the node preceding it. Node: a composite type (struct/class) that has member(s) as pointer(s) of its type. 5. 10. 4. 7. 2. NULL. A linked list.
E N D
Chapter 13 Pointers and Linked Lists
Nodes and Linked Lists • Linked list: A sequence of nodes in which each node is linked or connected to the node preceding it. • Node: a composite type (struct/class) that has member(s) as pointer(s) of its type. 5 10 4 7 2 NULL A linked list A node
Node • Is a composite type (struct/class) with at least 2 members: • The first one is the data • The second one is the pointer point to the next element in the list. • Ex: struct Node { int data; Node *link; } typedef Node* NodePtr;
Arrow Operator (->) • Used only with pointer variable. • Simplifies the notation specifying the members of a struct (or a class). • Combining the actions of dereferencing operator (*) and a dot operator (.) to specify a member of a dynamic struct or object that is pointed to by a pointer. • Those statements are equivalent: head-> data = 5; (*head).data = 5;
Accessing members of a Node • Using dot operator: (*head).data = 5; • Using arrow operator (more convenient): head-> data = 5;
Linked List • Each linked list starts with a pointer head which points to the first element in the list. • Ex: Node *head; NodePtr head; • Since the last element in the list doesn’t point to anything, its pointer is assigned NULL to signify the end. • If head is a pointer to the biginning of list and head == NULL, then the list is empty. 5 10 4 7 2 NULL head head NULL
Operations on a Linked list • Pass in the head pointer but always assign to a local variable or you can lose the head of the list. • The head pointer must be preserved or the whole list is lost. • Only pass by referenceif the head needs to be changed (to insert or delete at the head of the list)
Initialize a list // create a new node pointer NodePtr head; // point it to a new node head = new Node; // initialize a value for data head->data = 5; // end the list with NULL head->link = NULL; head ? head head ? 5 5 NULL head
Inserting a Node at the Head of a List • Precondition: The pointer argument head points to the beginning of the linked list. • Postcondition: A new node containing num added at the beginning of the linked list. • Pseudocode: • Create a new dynamic variable pointed to by temp. • Place the data in this new node. • Make the link member of this new node point to the first node of the original linked list. • Make the pointer variable named head point to the new node.
Inserting a Node at the Head of a List (code) Before function call HeadInsert(head, 3) void HeadInsert (NodePtr& head, int num) { NodePtr temp; temp = new Node; temp->data = num; temp->link = head; head = temp; } 0 temp ? 1 temp temp temp head head head head head 5 5 5 5 5 5 NULL NULL NULL NULL NULL NULL head 3 3 3 3 2 3 4 5 Finish function call
Losing Nodes Before function call HeadInsert(head, 3) void HeadInsert (NodePtr& head, int num) { NodePtr temp; temp = new Node; temp->data = num; //temp->link = head; head = temp; } 0 temp ? 1 temp temp head head head head 5 5 5 5 5 NULL NULL NULL NULL NULL head 3 3 3 2 3 Memory leak: caused by dynamic variables not returning their memory when they are out of scope. 4 After function call
Insert a Node in the middle of the list Before function call insert(AfterMe, 6) // Precondition: afterMe points to a node // in the linked list // Postcondition: A new node containing num // is added after the node pointed by afterMe void insert (NodePtrafterMe, int num) { NodePtr temp; temp = new Node; temp->data = num; temp->link = afterMe->link; afterMe->link = temp; } 5 5 5 5 5 0 1 2 3 AfterMe AfterMe AfterMe AfterMe AfterMe temp temp temp 6 6 6 6 7 7 7 7 7 NULL NULL NULL NULL NULL 3 3 3 3 3 head head head head head 4 6 5 After function call
Remove a Node from the list Before function call remove(head, 6) fromempty list 5 5 5 6 6 6 7 7 7 1 0 1 0 2 After function call Before function call remove(head, 3) NULL NULL NULL NULL NULL 3 3 head head head head head After function call // Precondition: head is a linked list // Postcondition: A new linked list NOT // containing num void remove (NodePtr head, int num) { if (head == NULL) { cout << "The list is empty."; return; } if (head->data == num) head = head->link; else { NodePtr before = head; NodePtr discard = head->link; while (discard->data < num && discard->link != NULL) { before = discard; discard = discard->link; } if (discard->link == NULL) // the last node cout << num << " is not in the list\n"; else if (discard->data == num) { before->link = discard->link; discard->link = NULL; // optional } } }
Remove a Node from the list Before function call remove(head, 9) 5 5 5 5 5 6 6 6 6 6 7 7 7 7 7 3 4 0 2 1 discard before discard discard before before NULL NULL NULL NULL NULL 3 3 3 3 3 head head head head head After function call // Precondition: head is a linked list // Postcondition: A new linked list NOT // containing num void remove (NodePtr head, int num) { if (head == NULL) { cout << "The list is empty."; return; } if (head->data == num) head = head->link; else { NodePtr before = head; NodePtr discard = head->link; while (discard->data < num && discard->link != NULL) { before = discard; discard = discard->link; } if (discard->link == NULL) // the last node cout << num << " is not in the list\n"; else if (discard->data == num) { before->link = discard->link; discard->link = NULL; } } }
Remove a Node from the list Before function call remove(head, 6) 5 5 5 5 5 6 6 6 6 7 7 7 7 7 3 4 2 5 1 0 discard discard discard before before before NULL NULL NULL NULL NULL 3 3 3 3 3 head head head head head After function call // Precondition: head is a linked list // Postcondition: A new linked list NOT // containing num void remove (NodePtr head, int num) { if (head == NULL) { cout << "The list is empty."; return; } if (head->data == num) head = head->link; else { NodePtr before = head; NodePtr discard = head->link; while (discard->data < num && discard->link != NULL) { before = discard; discard = discard->link; } if (discard->link == NULL) // the last node cout << num << " is not in the list\n"; else if (discard->data == num) { before->link = discard->link; discard->link = NULL; } } }
Remove a Node from the list Before function call remove(head, 6) 5 5 5 5 5 6 6 6 6 7 7 7 7 7 3 4 2 5 1 0 discard discard discard before before before NULL NULL NULL NULL NULL 3 3 3 3 3 head head head head head After function call // Precondition: head is a linked list // Postcondition: A new linked list NOT // containing num void remove (NodePtr head, int num) { if (head == NULL) { cout << "The list is empty."; return; } if (head->data == num) head = head->link; else { NodePtr before = head; NodePtr discard = head->link; while (discard->data < num && discard->link != NULL) { before = discard; discard = discard->link; } if (discard->link == NULL) // the last node cout << num << " is not in the list\n"; else if (discard->data == num) { before->link = discard->link; discard->link = NULL; } } }
Doubly linked list Each node has 2 pointers forward and back. structNode { int data; Node* forward; Node* back; }; NULL 5 NULL 3 7 back front
Binary Tree Each node has 2 pointers left and right. structTreeNode { int data; Node* left; Node* right; }; root 40 20 50 10 30 NULL 60 NULL NULL NULL NULL NULL NULL
Stacks • A data structure that retrieves data in the reverse of the order in which the data is stored. • Last In First Out (LIFO) A B C CBA BA STORE A A C B RETRIEVE BA A
Stack Class #ifndef STACK_H #define STACK_H struct StackFrame { char data; StackFrame *link; }; typedef StackFrame* StackFramePtr; class Stack { public: Stack (); // Initializes the object to an empty stack Stack (const Stack& aStack); // Copy constructor ~Stack (); // Destroys the stack and returns free all memory void push (char symbol); // Post condition: symbol has been added to the stack char pop (); // Precondition: The stack is NOT empty // Returns the top symbol on the stack and // remove that top symbol from the stack bool empty () const; // Returns true if the stack is empty. Returns false otherwise. private: StackFramePtr top; }; #endif
Queues • A data structure that retrieves data in the order in which the data is stored. • First In First Out (FIFO)
Queues A B C CBA BA STORE A CB C RETRIEVE B A data structure that retrieves data in the order in which the data is stored. First In First Out (FIFO) C A
Queue Class class Queue { public: Queue (); // Initializes the object to an empty queue Queue (const Queue& aQueue); // Copy constructor ~Queue (); // Destroys the queue and returns free all memory void add (char item); // Post condition: item has been added to the back of the queue char remove (); // Precondition: The queue is NOT empty // Returns the item at the front of the queue and // remove that top item from the queue bool empty () const; // Returns true if the queue is empty. Returns false otherwise. private: QueueNotePtr top; // points to the head of the linked list QueueNotePtr back // points to the node at the other end of the // linked list. Items are added at this end. }; #endif #ifndef QUEUE_H #define QUEUE_H struct QueueNote { char data; QueueNote *link; }; typedef QueueNote * QueueNotePtr;