Download presentation
Presentation is loading. Please wait.
Published byLuke Harvey Modified over 8 years ago
1
CHAPTER 17 LINKED LISTS
2
In this chapter, you will: Learn about linked lists Become aware of the basic properties of linked lists Explore the insertion and deletion operations on linked lists Discover how to build and manipulate a linked list Learn how to construct a doubly linked list
3
Storing and processing data in an array has limitations. Array size is fixed. So only a fixed number of items can be stored in an array. Searching for an item in an array is time consuming if data is not sorted. If data is sorted, item insertion and deletion becomes time consuming.
4
struct nodeType { int info; nodeType *link; }; //variable declaration nodeType* head; Linked list: A list of items, called nodes, in which the order of the nodes is determined by the address, called the link, stored in each node. The address of the first node of the list is stored in a separate location, called head or first.
5
Linked Lists: Some Properties
6
current = head;
7
current = current->link;
9
Traversing a Linked List current = head; while(current != NULL) { cout info<<" "; current = current->link; } Item Insertion and Deletion Assume info type is int. struct nodeType { int info; nodeType *link; }; nodeType *head, *p, *q, *newNode;
10
newNode = new nodeType; //create newNode newNode->info = 50; //store 50 in the new node Insertion A new node with info 50 is to be created and inserted after p. newNode->link = p->link; p->link = newNode; newNode->link = p->link;
11
p->link = newNode;
12
Deletion of a Node Suppose the node with info 34 is to be deleted from the list q = p->link; p->link = q->link; delete q;.
13
Building a Linked List Building a Linked List Forward Suppose that the nodes are in the usual info-link form with info of the type int. Let us assume that we process the following data. 2, 15, 8, 24, 34 We need three pointers to build the list. One pointer to point to the first node in the list. This pointer cannot be moved. One pointer is needed to point to the last node in the list. One pointer to create the new node.
14
nodeType *first, *last, *newNode; int num; first = NULL;//initialize the pointer last = NULL; 1 cin>>num; 2newNode = new nodeType; 3newNode->info = num; 4newNode->link = NULL; 5if (first == NULL) //empty list { 5afirst = newNode; 5blast = newNode; } 6else//append to the end { 6alast->link = newNode; 6blast = newNode; }
15
Initially both first and last are NULL. After statement 1, num is 2. Statement 2 creates a node and stores the address of the node in newNode. Statement 3 stores 2 in the info field of newNode and statement 4 stores NULL in the link field of newNode.
16
Since first is NULL, statements 5a and 5b execute Repeat statements 1-6b:
17
Since first is not NULL, statements 6a and 6b execute Repeat statements 1-6b three more times.
18
nodeType* buildListForward() { nodeType *first, *newNode, *last; int num; cout<<"Enter a list of integers ending with -999.\n"; cin>>num; first = NULL; while(num != -999)//-999 is sentinel { newNode = new nodeType; newNode->info = num; newNode->link = NULL; if(first == NULL) { first = newNode; last = newNode; } else { last->link = newNode; last = newNode; } cin>>num; }//end while return first; }//end buildListForward
19
Building the Linked List Backward For the above data, that is, 2, 15, 8, 24, and 34, the linked list is: 1. Initialize first to NULL. 2. For each item in the list, a. Create the new node, newNode. b. Store the item in newNode. c. Insert newNode before first. d. Update the value of the pointer first.
20
nodeType* buildListBackward() { nodeType *first, *newNode; int num; cout<<"Enter a list of integers ending with -999.\n"; cin>>num; first = NULL; while (num != -999) { newNode = new nodeType; //create a node newNode->info = num; //store the data in newNode newNode->link = first; //put newNode at the //beginning of the list first = newNode; //update the head pointer //of the list, that is, first cin>>num; //read the next number } return first; }//end buildListBackward
21
Linked List as an ADT The basic operations on linked lists are: 1. Initialize the list initializeList 2. Check if the list is empty. isEmptyList 3. Check if the list is full. isFullList 4. Search the list for a given item. search 5. Insert an item in the list. insertFirst, insertLast 6. Delete an item from the list. deleteNode 7. Destroy the list. destroyList 8. Print the list. print 9. Retrieve the info contained in the first node. retrieveFirst
22
//Definition of the node struct nodeType { int info; nodeType *link; }; class linkedListType { public: void initializeList(); bool isEmptyList(); bool isFullList(); void print(); int length(); void destroyList(); void retrieveFirst(int& firstElement); void search(const int& searchItem); void insertFirst(const int& newItem); void insertLast(const int& newItem); void deleteNode(const int& deleteItem); linkedListType(); linkedListType(const linkedListType& otherList); //copy constructor ~linkedListType(); //destructor protected: nodeType *first; //pointer to the first node of the list nodeType *last; //pointer to the last node of the list };
23
linkedListType::linkedListType()//default Constructor { first = NULL; last = NULL; } bool linkedListType::isEmptyList() {return(first == NULL); } bool linkedListType::isFullList() {return false; } int linkedListType::length() { int count = 0; nodeType *current; //pointer to traverse the list current = first; while (current!= NULL) { count++; current = current->link; } return count; } //end length
24
Destroy void linkedListType::destroyList() { nodeType *temp; //pointer to deallocate the // memory occupied by the node while(first != NULL) //while there are nodes in the list { temp = first; //set temp to the current node first = first->link; //advance first to the next node delete temp; //deallocate memory occupied by temp } last = NULL; //initialize last to NULL; first has //already been set to NULL by the while loop }
25
InitializeList void linkedListType::initializeList() { destroyList(); //if the list has any nodes, delete them } Print List void linkedListType::print() { nodeType *current; current = first; while(current != NULL) //while more data to print { cout info<<" "; current = current->link; } }//end print void linkedListType::retrieveFirst(int& firstElement) { firstElement = first->info; }//end retrieveFirst
26
Search 1. Compare the search item with the current node in the list. if the info of the current node is same as the search item, stop the search; otherwise make next node as the current node. 2. Repeat step 1 until either we have found the item or there is no more data left in the list to compare with the search item. void linkedListType:search(const int& item) { nodeType *current; //pointer to traverse the list bool found; if(first == NULL) //list is empty cout<<"Cannot search an empty list. "<<endl; else { current = first; //set current to point to the first node in the list found = false; //set found to false while(!found && current != NULL) //search the list if(current->info == item) //item is found found = true; else current = current->link; //make current point to the next node if(found) cout<<"Item is found in the list."<<endl; else cout<<"Item is not found in the list."<<endl; } //end else }//end search
27
Insert First 1. Create a new node. 2. Store the new item in the new node. 3. Insert the node before first. void linkedListType::insertFirst(const int& newItem) { nodeType *newNode; //pointer to create the new node newNode = new nodeType; newNode->info = newItem; newNode->link = first; first = newNode; if(last == NULL) last = newNode; }
28
Insert Last void linkedListType::insertLast(const int& newItem ) { nodeType *newNode; newNode = new nodeType; newNode->info = newItem; newNode->link = NULL; if(first == NULL) { first = newNode; last = newNode; } else { last->link = newNode; last = newNode; } }//end insertLast
29
Insert in an ordered list void linkedListType::insertNode(const int& newItem) { nodeType *current; nodeType *trailCurrent; // pointer just before current nodeType *newNode; //pointer to create a node bool found; newNode = new nodeType; newNode->info = newItem; newNode->link = NULL; if(first == NULL) first = newNode; else { current = first; found = false; while (current != NULL && !found) //search for a place to insert if (current->info >= newitem) found = true; else { trailCurrent = current; current = current->link; } if (current == first) // Case 2 { newNode->link = first; first = newNode; } else// Case 3 { trailCurrent->link = newNode; newNode->link = current; } } //end else }//end insertLast
30
Delete Node We need to consider several cases. 1. The list may be empty. 2. The first node may be the node with the given info. In this case we need to adjust the pointer first. 3. The node with the given info is somewhere in the list. If the node to be deleted is the last node, then we must adjust the pointer last. 4. The list does not contain the node with the given info.
31
Case 1: List is empty. If the list is empty, output an error message Case 2: List is not empty. The node to be deleted is the first node. After deletion, the list becomes empty. Therefore, after deletion, both first and last are set to NULL.
32
Case 2: List is not empty. The node to be deleted is the first node. Consider the list of more than one node, as shown in Figure 17-28.
33
Case 3: Node to be deleted is not the first node, but is somewhere in this list. Case 3a: Node to be deleted is not the last node.
34
Case 3b: Node to be deleted is the last node.
35
void linkedListType::deleteNode(const int& deleteItem) { nodeType *current; //pointer to traverse the list nodeType *trailCurrent; //pointer just before current bool found; if(first == NULL) //Case 1; list is empty. cout<<"Can not delete from an empty list.\n"; else {if(first->info == deleteItem) //Case 2 { current = first; first = first->link; if(first == NULL) //list had only one node last = NULL; delete current; } else //search the list for the node with the given info { found = false; trailCurrent = first; //set trailCurrent to point to the first node current = first->link; //set current to point to the second node while((!found) && (current != NULL)) { if(current->info != deleteItem) { trailCurrent = current; current = current->link; } else found = true; } //end while
36
if(found) //Case 3; if found, delete the node { trailCurrent->link = current->link; if(last == current) //node to be deleted was the last node last = trailCurrent; delete current; //delete the node from the list } else cout<<"Item to be deleted is not in the list." <<endl; } //end else } //end deleteNode
37
Destructor linkedListType::~linkedListType() //destructor { nodeType *temp; while(first != NULL) { temp = first; first = first->link; delete temp; }//end while last = NULL; }//end destructor
38
Copy Constructor linkedListType::linkedListType (const linkedListType& otherList) { nodeType *newNode; nodeType *current; if(otherList.first == NULL) //otherList is empty { first = NULL; last = NULL; } else { current = otherList.first; //current points to the list to be copied //copy the first node first = new nodeType; //create the node first->info = current->info; //copy the info first->link = NULL; //set the link field of the node to NULL last = first; //make last point to the first node current = current->link; //make current point to the next node //copy the remaining list while(current != NULL) { newNode = new nodeType; newNode->info = current->info; newNode->link = NULL; last->link = newNode; last = newNode; current = current->link; }//end while }//end else }//end copy constructor
39
Overloading the Assignment Operator const linkedListType& linkedListType::operator=(const linkedListType& otherList) { nodeType *newNode; nodeType *current; if(this != &otherList) //avoid self-copy { if(first != NULL) destroyList(); if(otherList.first == NULL) //otherList is empty { first = NULL; last = NULL; } else { current = otherList.first; //copy the first element first = new nodeType; first->info = current->info; first->link = NULL; last = first; current = current->link; //copy the remaining list while(current != NULL) { newNode = new nodeType; newNode->info = current->info; newNode->link = NULL; last->link = newNode; last = newNode; current = current->link; }//end while }//end else return *this; }
40
Doubly Linked Lists A doubly linked list is a linked list in which every node has a next and a back pointer. A doubly linked list can be traversed in either direction. We can traverse the list starting at the first node or if a pointer to the last node is given, we can traverse the list starting at the last node.
41
Operations on a doubly linked list are : 1. Initialize the list. 2. Destroy the list. 3. Check whether the list is empty. 4. Check whether the list is full. 5. Search the list for a given item. 6. Insert an item in the list. 7. Delete an item from the list. 8. Find the length of the list. 9. Print the list.
42
//Definition of the node struct nodeType { int info; nodeType *next; nodeType *back; }; class doublyLinkedList { public: const doublyLinkedList& operator= (const doublyLinkedList &); void initializeList(); bool isEmptyList(); void destroy(); void print(); int length(); void search(const int& searchItem); void insertNode(const int& insertItem); void deleteNode(const int& deleteItem); doublyLinkedList(); doublyLinkedList(const doublyLinkedList& otherList); //copy constructor ~doublyLinkedList(); private: nodeType *first; //pointer to the list };
43
doublyLinkedList::doublyLinkedList() //default constructor { first= NULL; } bool doublyLinkedList::isEmptyList() { return(first == NULL); }
44
void doublyLinkedList::destroy() { nodeType *temp; //pointer to delete the node while(first != NULL) { temp = first; first = first->next; delete temp; } void doublyLinkedList:: initializeList () { destroy(); }
45
Length of the List int doublyLinkedList::length() { int length = 0; nodeType *current; //pointer to traverse the list current = first; //set current to point to the first node while(current != NULL) { length++; //increment the length current = current->next; //advance current } return length; }
46
Print List void doublyLinkedList::print() { nodeType *current; //pointer to traverse the list current = first; //set current to point to the first node while(current != NULL) { cout info<<" "; //output info current = current->next; }//end while }//end print
47
void doublyLinkedList::search(const int& searchItem) { bool found; nodeType *current; //pointer to traverse the list if(first == NULL) cout<<"Cannot search an empty list"<<endl; else { found = false; current = first; while(current != NULL && !found) if(current->info >= searchItem) found = true; else current = current->next; if(current == NULL) cout<<"Item not in the list"<<endl; else if(current->info == searchItem) //test for //equality cout<<"Item is found in the list"<<endl; else cout<<"Item not in the list"<<endl; }//end else }//end search
48
insertNode Four cases: 1. Insertion in an empty list 2. Insertion at the beginning of a nonempty list 3. Insertion at the end of a nonempty list 4. Insertion somewhere in a nonempty list
49
Consider the double linked list shown in Figure 17-45. After inserting 20, the resulting list is as shown in Figure 17-46.
50
void doublyLinkedList::insertNode(const int& insertItem) { nodeType *current; //pointer to traverse //the list nodeType *trailCurrent; //pointer just before //current nodeType *newNode; //pointer to create a node bool found; newNode = new nodeType; //create the node newNode->info = insertItem; //store the new item //in the node newNode->next = NULL; newNode->back = NULL;
51
if(first == NULL) //if list is empty, newNode is //the only node first = newNode; else { found = false; current = first; while(current != NULL && !found) //search the list if(current->info >= insertItem) found = true; else { trailCurrent = current; current = current->next; } if(current == first) //insert newNode before the firstnode { first->back = newNode; newNode->next = first; first = newNode; }
52
else { //insert newNode between trailCurrent and current if(current != NULL) { trailCurrent->next = newNode; newNode->back = trailCurrent; newNode->next = current; current ->back = newNode; } else { trailCurrent->next = newNode; newNode->back = trailCurrent; } }//end else }//end insertNode
53
Delete Node The delete operation has several cases: 1. The list is empty. 2. The item to be deleted is in the first node of the list, which would require us to change the value of the pointer first. 3. The item to be deleted is somewhere in the list. 4. The item to be deleted is not in the list.
54
Case 3. Consider the list shown in Figure 17-47.
55
List after deleting 17 is shown in Figure 17-49.
56
Delete Node void doublyLinkedList::deleteNode(const int& deleteItem) { nodeType *current; //pointer to traverse the list nodeType *trailCurrent; //pointer just before //current bool found; if(first == NULL) cout<<"Cannot delete from an empty list"<<endl; else if(first->info == deleteItem) //node to be deleted { //is the first node current = first; first = first->next; if(first != NULL) first->back = NULL; delete current; }
57
else { found = false; current = first; while(current != NULL && !found) //search the list if(current->info >= deleteItem) found = true; else current = current->next; if(current == NULL) cout<<"Item to be deleted is not in the list" <<endl; else if(current->info == deleteItem) //check for equality { trailCurrent = current->back; trailCurrent->next = current->next; if(current->next != NULL) current->next->back = trailCurrent; delete current; } else cout<<"Item to be deleted is not in list." <<endl; }//end else }//end deleteNode
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.