Download presentation
Presentation is loading. Please wait.
Published byAbner Alexander Modified over 5 years ago
1
Sequences 08/30/17 08/30/17 Unit III. Linked Lists 1
2
Introduction Definitions Advantages Lists and arrays
Nodes and pointers Single Linked Lists Double Linked Lists Circular Lists Advantages
3
Lists and arrays Lists
4
Lists and arrays Arrays: Index 1 2 3 Value 44 5 96
{Size of the following array is = 4} Index 1 2 3 Value 44 5 96
5
Introduction Definitions Advantages Lists and arrays
Nodes and pointers Single Linked Lists Double Linked Lists Circular Lists Advantages
6
Nodes and pointers
7
Introduction Definitions Advantages Lists and arrays
Nodes and pointers Single Linked Lists Double Linked Lists Circular Lists Advantages
8
Single linked lists
9
Introduction Definitions Advantages Lists and arrays
Nodes and pointers Single Linked Lists Double Linked Lists Circular Lists Advantages
10
Double Linked Lists
11
Introduction Definitions Advantages Lists and arrays
Nodes and pointers Single Linked Lists Double Linked Lists Circular Lists Advantages
12
Circular Lists
13
Introduction Definitions Advantages Lists and arrays
Nodes and pointers Single Linked Lists Double Linked Lists Circular Lists Advantages
14
Advantages The Linked List advantages are collected because of the array disadvantages, array disadvantages are: Array Size Memory allocation Insertion and Deletion
15
Linked LIst A linked list is an ordered collection of data in which each element (node) contains a minimum of two values, data and link(s) to its successor (and/or predecessor). 15
16
Example: shelf & books arrangement(sequentially)
Let Books = {book1, book2, book3, …, book10} 16
17
Shelf and books arranged in a distributed manner
17
18
Sequential organization features
1. Successive elements of a list are stored a fixed distance apart. 2. It provides static allocation, which means, the space allocation done by a compiler once cannot be changed during execution, and the size has to be known in advance. 3. As individual objects are stored a fixed distance apart, we can access any element randomly. 18
19
Cont.. 4. Insertion & deletion of objects in between the list require a lot of data movement. 5. It is space inefficient for large objects with frequent insertions and deletions. 6. An element need not know/store and keep the address of its successive element. 19
20
Linked organization 1.Elements can be placed anywhere in the memory.
2. Dynamic allocation (size need not be known in advance), i.e. space allocation as per need can be done during execution. 3. As objects are not placed in consecutive locations at a fixed distance apart, random access to elements is not possible. 4. Insertion and deletion of objects do not require any data shifting. 5. It is space efficient for large objects with frequent insertions and deletions 20
21
Cont.. 6. Each element in general is a collection of data and a link. At least one link field is a must. 7. Every element keeps the address of its successor element in a link field. 8. The only burden is that we need additional space for the link field for each element. However, additional space is not a severe penalty when large objects are to be stored. 9. Linked organization needs the use of pointers and dynamic memory allocation. 21
22
Preliminaries Figure a) A linked list of integers; b) insertion; c) deletion
23
Pointers A pointer contains the location, or address in memory, of a memory cell Initially undefined, but not NULL A statically allocated pointer declaration int *p; A dynamically allocated pointer variable p = new int;
24
Pointers The expression, *p, denotes the memory cell to which p points
The & address-of operator places the address of a variable into a pointer variable p = &x; Figure A pointer to an integer
25
Pointers The delete operator returns dynamically allocated memory to the system for reuse, and leaves the variable undefined delete p; A pointer to a deallocated memory cell is possible and dangerous Assign the pointer q the value in p q = p;
26
Pointers Figure (a) declaring pointer variables; (b) pointing to statically allocating memory; (c) assigning a value; (d) allocating memory dynamically; (e) assigning a value
27
Pointers Figure (f) copying a pointer;
(g) allocating memory dynamically and assigning a value; (h) assigning NULL to a pointer variable; (i) deallocating memory
28
Dynamic Allocation of Arrays
Use the new operator to allocate an array dynamically An array name is a pointer to the array’s first element The size of a dynamically allocated array can be increased double* oldArray = anArray; anArray = new double[2*arraySize];
29
Pointer-Based Linked Lists
A node in a linked list is usually a struct struct Node { int item Node *next; }; //end struct A node is dynamically allocated Node *p; p = new Node;
30
Pointer-Based Linked Lists
The head pointer points to the first node in a linked list If head is NULL, the linked list is empty Executing the statement the statement head=new Node before head=NULL will result in a lost cell
31
Pointer-Based Linked Lists
Figure A head pointer to a list Figure A lost cell
32
Linked List terminology
Header node: a special node that is attached at the beginning of the linked list. This header node may contain special information (metadata) about the linked list 32
33
Cont… Data node: store the data members and link(s) to its predecessor (and/or successor). Head pointer: store the data members and link(s) to its predecessor (and/or successor). Tail pointer :Similar to the head pointer that points to the first node of a linked list 33
34
1 Introduction to the Linked List ADT
A linked list is a series of connected nodes, where each node is a data structure. A linked list can grow or shrink in size as the program runs 34
35
Advantages of Linked Lists over Arrays
A linked list can easily grow or shrink in size. Insertion and deletion of nodes is quicker with linked lists than with vectors. 35
36
The composition of a Linked List
Each node in a linked list contains one or more members that represent data. In addition to the data, each node contains a pointer, which can point to another node. 36
37
The composition of a Linked List
A linked list is called "linked" because each node in the series has a pointer that points to the next node in the list. 37 37
38
Primitive Operations 1. Creating an empty list 2. Inserting a node
3. Deleting a node 4. Traversing the list 38
39
Some more operations 5. Searching a node 6. Updating a node
7. Printing the node or list 8. Counting the length of the list 9. Reversing the list 10. Sorting the list using pointer manipulation 11. Concatenating two lists 12. Merging two sorted lists into a third sorted list 39
40
Realization of Linked List Using 1D arrays
40
41
Realization of linked list using 2D arrays L = {100, 102, 20, 51, 83, 99, 65}, Max = 10 and Head = 2. 41
42
dynaMiC MeMORy ManageMent
Memory allocation process: 42
43
Using new & delete operator
Syntax Pointer_Type_Variable = new Data_Type; 1. int *Number; Number = new int(20); 2. Time *timeptr; timeptr = new Time 2. Time *timeptr; timeptr = new Time; 3. Date *B_Date_Ptr, *Today; B_Date_ptr = new Date(20, 1, 1969); Today = new Date(20, 1, 2005); 43
44
Delete operator delete ptr;
If we want to free a dynamically allocated array, the following is the syntax: delete[] pointer_variable; 44
45
#include<iostream.h> int main() { int *ptr1, *ptr2;
ptr1 = new int; *ptr1 = 52; cout << "*ptr1 = " << *ptr1 << endl; cout << "*ptr2 = " << *ptr2 << endl; *ptr2 = 63; ptr1 = new int; *ptr1 = 98; cout << "*ptr1 = " << *ptr1 << endl; cout << "*ptr2 = " << *ptr2 << endl; return 0; } 45
46
output *ptr1 = 52 *ptr2 = Garbage *ptr2 = 63 *ptr1 = 98 46
47
Declarations First you must declare a data structure that will be used for the nodes. For example, the following struct could be used to create a list where each node holds a float: struct ListNode { float value; struct ListNode *next; }; 47
48
declaration class Llist { private: Node *Head; public: LList();
: ¸ ˝ ˛ member functions here : }; 48
49
Declarations The next step is to declare a pointer to serve as the list head, as shown below. ListNode *head; Once you have declared a node data structure and have created a NULL head pointer, you have an empty linked list. The next step is to implement operations with the list. 49
50
2 Linked List Operations
We will use the following class declaration (on the next slide), which is stored in FloatList.h. 50
51
class FloatList { private:. // Declare a structure for the list
class FloatList { private: // Declare a structure for the list struct ListNode { float value; struct ListNode *next; }; ListNode *head; // List head pointer public: FloatList(void) // Constructor { head = NULL; } ~FloatList(void); // Destructor void appendNode(float); void insertNode(float); void deleteNode(float); void displayList(void); }; 51
52
Appending a Node to the List
To append a node to a linked list means to add the node to the end of the list. The pseudocode is shown below. The C++ code follows. Create a new node. Store data in the new node. If there are no nodes in the list Make the new node the first node. Else Traverse the List to Find the last node. Add the new node to the end of the list. End If. 52
53
void FloatList::appendNode(float num) {. ListNode. newNode,. nodePtr;
void FloatList::appendNode(float num) { ListNode *newNode, *nodePtr; // Allocate a new node & store num newNode = new ListNode; newNode->value = num; newNode->next = NULL; // If there are no nodes in the list // make newNode the first node if (!head) head = newNode; else // Otherwise, insert newNode at end { // Initialize nodePtr to head of list nodePtr = head; // Find the last node in the list while (nodePtr->next) nodePtr = nodePtr->next; // Insert newNode as the last node nodePtr->next = newNode; } } 53
54
Program -1 // This program demonstrates a simple append // operation on a linked list. #include <iostream.h> #include "FloatList.h” void main(void) { FloatList List; list.appendNode(2.5); list.appendNode(7.9); list.appendNode(12.6); } (This program displays no output.) 54
55
Stepping Through the Program
The head pointer is declared as a global variable. head is automatically initialized to 0 (NULL), which indicates that the list is empty. The first call to appendNode passes 2.5 as the argument. In the following statements, a new node is allocated in memory, 2.5 is copied into its value member, and NULL is assigned to the node's next pointer. 55
56
newNode = new ListNode;. newNode->value = num;
newNode = new ListNode; newNode->value = num; newNode->next = nULL; 56
57
The next statement to execute is the following if statement.
if (!head) head = newNode; There are no more statements to execute, so control returns to function main. 57
58
In the second call to appendNode, 7. 9 is passed as the argument
In the second call to appendNode, 7.9 is passed as the argument. Once again, the first three statements in the function create a new node, store the argument in the node's value member, and assign its next pointer to NULL. 58
59
Since head no longer points to NULL, the else part of the if statement executes:
else // Otherwise, insert newNode at end { // Initialize nodePtr to head of list nodePtr = head; // Find the last node in the list while (nodePtr->next) nodePtr = nodePtr->next; // Insert newNode as the last node nodePtr->next = newNode; } 59
60
nodePtr is already at the end of the list, so the while loop immediately terminates. The last statement, nodePtr->next = newNode; causes nodePtr->next to point to the new node. This inserts newNode at the end of the list. 60
61
The third time appendNode is called, 12. 6 is passed as the argument
The third time appendNode is called, 12.6 is passed as the argument. Once again, the first three statements create a node with the argument stored in the value member. 61
62
next, the else part of the if statement executes
next, the else part of the if statement executes. As before, nodePtr is made to point to the same node as head. 62
63
Since nodePtr->next is not NULL, the while loop will execute
Since nodePtr->next is not NULL, the while loop will execute. After its first iteration, nodePtr will point to the second node in the list. 63
64
The figure above depicts the final state of the linked list.
The while loop's conditional test will fail after the first iteration because nodePtr->next now points to NULL. The last statement, nodePtr->next = newNode; causes nodePtr->next to point to the new node. This inserts newNode at the end of the list The figure above depicts the final state of the linked list. 64
65
Traversing the List The displayList member function traverses the list, displaying the value member of each node. The following pseudocode represents the algorithm. The C++ code for the member function follows on the next slide. Assign List head to node pointer. While node pointer is not NULL Display the value member of the node pointed to by node pointer. Assign node pointer to its own next member. End While. 65
66
void FloatList::displayList(void) {. ListNode. nodePtr;
void FloatList::displayList(void) { ListNode *nodePtr; nodePtr = head; while (nodePtr) { cout << nodePtr->value << endl; nodePtr = nodePtr->next; } } 66
67
Program -2 // This program calls the displayList member function. // The funcion traverses the linked list displaying // the value stored in each node. #include <iostream.h> #include "FloatList.h" void main(void) { FloatList List; list.appendNode(2.5); list.appendNode(7.9); list.appendNode(12.6); list.displayList(); } 67
68
Program -2 Output 68
69
Inserting a Node Using the listNode structure again, the pseudocode on the next slide shows an algorithm for finding a new node’s proper position in the list and inserting there. The algorithm assumes the nodes in the list are already in order. 69
70
Create a new node. Store data in the new node
Create a new node. Store data in the new node. If there are no nodes in the list Make the new node the first node. Else Find the first node whose value is greater than or equal the new value, or the end of the list (whichever is first). Insert the new node before the found node, or at the end of the list if no node was found. End If. 70
71
The entire insertNode function begins on the next slide.
The code for the traversal algorithm is shown below. (As before, num holds the value being inserted into the list.) // Initialize nodePtr to head of list nodePtr = head; // Skip all nodes whose value member is less than num. while (nodePtr != NULL && nodePtr->value < num) { previousNode = nodePtr; nodePtr = nodePtr->next; } The entire insertNode function begins on the next slide. 71
72
Continued on next slide…
void FloatList::insertNode(float num) { ListNode *newNode, *nodePtr, *previousNode; // Allocate a new node & store Num newNode = new ListNode; newNode->value = num; // If there are no nodes in the list make newNode the first node if (!head) { head = newNode; newNode->next = NULL; } else // Otherwise, insert newNode. { // Initialize nodePtr to head of list nodePtr = head; // Skip all nodes whose value member is less than num. while (nodePtr != NULL && nodePtr->value < num) { previousNode = nodePtr; nodePtr = nodePtr->next; } Continued on next slide… 72
73
Continued from previous slide.
// If the new node is to be the 1st in the list, // insert it before all other nodes. if (previousNode == NULL) { head = newNode; newNode->next = nodePtr; } else { previousNode->next = newNode; newNode->next = nodePtr; } } } 73
74
Program 3 // This program calls the displayList member function. // The function traverses the linked list displaying // the value stored in each node. #include <iostream.h> #include "FloatList.h” void main(void) { FloatList list; // Build the list list.appendNode(2.5); list.appendNode(7.9); list.appendNode(12.6); // Insert a node in the middle of the list. list.insertNode(10.5); // Dispay the list list.displayList(); } 74
75
Program 3 Output 75
76
In insertNode, a new node is created and the function argument is copied to its value member. Since the list already has nodes stored in it, the else part of the if statement will execute. It begins by assigning nodePtr to head. 76
77
Since nodePtr is not NULL and nodePtr->value is less than num, the while loop will iterate. During the iteration, previousNode will be made to point to the node that nodePtr is pointing to. nodePtr will then be advanced to point to the next node. 77
78
Once again, the loop performs its test
Once again, the loop performs its test. Since nodePtr is not NULL and nodePtr->value is less than num, the loop will iterate a second time. During the second iteration, both previousNode and nodePtr are advanced by one node in the list. 78
79
This time, the loop's test will fail because nodePtr is not less than num. The statements after the loop will execute, which cause previousNode->next to point to newNode, and newNode->next to point to nodePtr. If you follow the links, from the head pointer to the NULL, you will see that the nodes are stored in the order of their value members. 79
80
Deleting a Node Deleting a node from a linked list requires two steps:
Remove the node from the list without breaking the links created by the next pointers Deleting the node from memory The deleteNode function begins on the next slide. 80
81
Continued on next slide…
void FloatList::deleteNode(float num) { ListNode *nodePtr, *previousNode; // If the list is empty, do nothing. if (!head) return; // Determine if the first node is the one. if (head->value == num) { nodePtr = head->next; delete head; head = nodePtr; } Continued on next slide… 81
82
Continued from previous slide.
else { // Initialize nodePtr to head of list nodePtr = head; // Skip all nodes whose value member is not equal to num. while (nodePtr != NULL && nodePtr->value != num) { previousNode = nodePtr; nodePtr = nodePtr->next; } // Link the previous node to the node after // nodePtr, then delete nodePtr. previousNode->next = nodePtr->next; delete nodePtr; } } 82
83
Program 4 Continued on next slide…
// This program demonstrates the deleteNode member function #include <iostream.h> #include "FloatList.h“ void main(void) { FloatList list; // Build the list list.appendNode(2.5); list.appendNode(7.9); list.appendNode(12.6); cout << "Here are the initial values:\n"; list.displayList(); cout << endl; cout << "Now deleting the node in the middle.\n"; cout << "Here are the nodes left.\n"; list.deleteNode(7.9); list.displayList(); cout << endl; Continued on next slide… 83
84
Continued from previous slide.
cout << "Now deleting the last node.\n"; cout << "Here are the nodes left.\n"; list.deleteNode(12.6); list.displayList(); cout << endl; cout << "Now deleting the only remaining node.\n"; cout << "Here are the nodes left.\n"; list.deleteNode(2.5); list.displayList(); } 84
85
Program Output Here are the initial values: 2. 5 7. 9 12
Program Output Here are the initial values: Now deleting the node in the middle. Here are the nodes left Now deleting the last node. Here are the nodes left Now deleting the only remaining node. Here are the nodes left. 85
86
Look at the else part of the second if statement
Look at the else part of the second if statement. This is where the function will perform its action since the list is not empty, and the first node does not contain the value 7.9. Just like insertNode, this function uses nodePtr and previousNode to traverse the list. The while loop terminates when the value 7.9 is located. At this point, the list and the other pointers will be in the state depicted in the figure below. 86
87
next, the following statement executes.
previousNode->next = nodePtr->next; The statement above causes the links in the list to bypass the node that nodePtr points to. Although the node still exists in memory, this removes it from the list. The last statement uses the delete operator to complete the total deletion of the node. 87
88
Destroying the List The class's destructor should release all the memory used by the list. It does so by stepping through the list, deleting each node one-by-one. The code is shown on the next slide. 88
89
FloatList::~FloatList(void) { ListNode *nodePtr, *nextNode;
nodePtr = head; while (nodePtr != NULL) { nextNode = nodePtr->next; delete nodePtr; nodePtr = nextNode; } } Notice the use of nextNode instead of previousNode. The nextNode pointer is used to hold the position of the next node in the list, so it will be available after the node pointed to by nodePtr is deleted. 89
90
Class Design for List The member variables are: Member functions
Node *head_ptr; Node *tail_ptr; int numOfItems; Member functions Node * search(int x); Node * itemAt(int position); void removeHead(); void removeTail(); void remove(int x); void insertHead(int x); void insertTail(int x); void insert(Node *p, int x) // inserts item after the item // pointed to by p int size( ); Node *getHead( ); Node getTail( ); bool isEmpty( ); 90 90
91
Class List Type class List { private:
Node *head_ptr; Node *tail_ptr; int numOfItems; public: List( ); // constructor int size( ); Node *getHead( ); Node *getTail( ); bool isEmpty( ); Node *search(int x); Node *itemAt(int position); void removeHead(); void removeTail(); void remove(int x); // delete leftmost item having x void insertHead(int x); void insertTail(int x); void insert(Node *p, int x); }; 91 91
92
Implementation of Class List
List::List( ){head_ptr= NULL; tail_ptr=NULL; numOfItems=0;}; int List::size( ){return numOfItems;}; Node * List::getHead( ) {return head_ptr;}; Node * List::getTail( ) {return tail_ptr;}; bool List::isEmpty() {return (numOfItem==0);}; 92 92
93
Searching for an Item Suppose you want to find the item whose data value is A You have to search sequentially starting from the head item rightward until the first item whose data member is equal to A is found. At each item searched, a comparison between the data member and A is performed. 93 93
94
Implementation of search( )
Node *List::search(int x){ Node * currentPtr = getHead( ); while (currentPtr != NULL){ if (currentPtr->getData( ) == x) return currentPtr; else currentPtr = currentPtr->getNext(); } return NULL; // Now x is not, so return NULL }; 94 94
95
Implementation of itemAt( )
Node *List::itemAt(int position){ if (position<0 || position>=numOfItems) return NULL; Node * currentPtr = getHead( ); for(int k=0;k != position; k++) currentPtr = currentPtr -> getNext( ); return currentPtr; }; 95 95
96
Time of the Operations Time to search() is O(L) where L is the relative location of the desired item in the List. In the worst case. The time is O(n). In the average case it is O(N/2)=O(n). Time for remove() is dominated by the time for search, and is thus O(n). Time for insert at head or at tail is O(1). Time for insert at other positions is dominated by search time, and thus O(n). Time for size() is O(1), and time for isEmpty() is O(1) 96 96
97
Traversing a SLL (animation)
here three two one numerals 97 97
98
Inserting after (animation)
2.5 node three two one numerals Find the node you want to insert after First, copy the link from the node that's already in the list Then, change the link in the node that's already in the list 98 98
99
Deleting a node from a SLL
In order to delete a node from a SLL, you have to change the link in its predecessor This is slightly tricky, because you can’t follow a pointer backwards Deleting the first node in a list is a special case, because the node’s predecessor is the list header 99 99
100
Deleting an element from a SLL
• To delete the first element, change the link in the header three two one numerals • To delete some other element, change the link in its predecessor three two one numerals (predecessor) • Deleted nodes will eventually be garbage collected 100 100
101
4 Variations of the Linked List
The Doubly-Linked List 101
102
4 Variations of the Linked List
The Circular Linked List 102
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.