Linked List
description
Transcript of Linked List
Linked ListLinked List
Linked List
Linked ListIs a series of connected nodes, where each
node is a data structure with data and pointer(s)
Advantages over array implementationCan grow and shrink in size, with no upper limitFast insertion and deletion
Ωhead
Node
struct nodeType { elemType data; nodeType *next;
}
nodeType *head;
data pointer to node
Note the recursive form of the data structureNote the recursive form of the data structure.Note the self-referencing form of the data structure.
head
Basic List Operations
Append (item) -- insert at back
InsertAtFront(item) --insert at front of list
InsertInOrder(iterm) -- insert in (some type of) order
Delete(item) -- remove a particular item
DestroyList() -- delete the entire list
IsEmpty() -- true if list is empty; false, otherwise
PrintList() -- for diagnostic purposes -- example of traversing a list (visiting each node in a list)
List Class Interface (list.h)typedef int elemType;class List {public: List(); // Constructor ~List(); // Destructor void append(elemType item); void insertAtFront(elemType item); void insertInOrder(elemType item); elemType removeFromFront(); void deleteNode(elemType item); void clear(); // remove all nodes bool isEmpty(); void print();private: struct nodeType {
elemType data; nodeType *next; // note “self-reference”
}; nodeType *head;};
List() Operation (Constructor)
A) Let head point to NULL
Ω
head Ω
In list.cpp, assume the following directive:
#define EMPTY -99999 // empty value
List(){ head = NULL;}
eeeeeenow
eieiieList::List() { head = NULL;}
insertAtFront(item) Operation
newNode
A) Declare newNode pointer
B) Create a new node, insert data
newNode xxx123 ΩΩ
head Ω
insertAtFront (item) Operation
C) Insert new node at front
newNode xxx123
head
Ω
Ω
void List::insertAtFront(elemType item){
// Prepare a new node nodeType *newNode; // pointer to new node newNode = new nodeType; // Create new node newNode->data = item; // Store data newNode->next = NULL;
// Insert new node at front newNode->next = head; head = newNode;}
insertAtFront(item) Operation
insertAtFront(item) Operation
Does this algorithm work with an empty list?
// Insert new node at front newNode->next = head; head = newNode;
Your Turn
Write a C++ implementation of a removeFromFront() method, which removes an item from the front of a list and returns the item removed.
elemType removeFromFront() Operation
temPtr
A) Declare temPtr
B) If (isEmpty()). . .
return EMPTYΩ
head Ω
elemType removeFromFront() Operation
Else . . . C) Let temPtr point to where head points to: temPtr head
temPtr Ω
head Ω
elemType removeFromFront() Operation
E) Save the item removed.
D) Let head point to the 2nd Node.
temPtr
head Ω
temPtr
head Ω
elemType result = temPtr->data;
elemType removeFromFront() Operation
G) Return the item removed.
F) Delete the node.
temPtr
head Ω
return result;
delete temPtr;
elemType List::removeFromFront item){ if (isEmpty()) return NULL;
nodePtr *temPtr; temPtr = head;
head = head->next;
elemType result = temPtr->data; delete temPtr; return result;}
elemType removeFromFront() Operation
Your Turn
Sketch a diagram of a linked list (with 5 nodes). Using the diagram, indicate the steps necessary to implement the append(item) method, which inserts an item at the end of the list.
append(item) Operation
temPtr newNode
A) Declare temPtr, newNode pointers
B) Create a new node, insert data
newNode xxx123 temPtr ΩΩ
head Ω
append(item) Operation
C) If list empty, make new node the first
D) Otherwise, find the last node
head Ω
newNode xxx123 Ω
temPtr
head Ω
append (item) Operation
E) Insert new node at end
temPtr
newNode xxx123
head
Ω
While temPtr.next != Null, move temPtr
temPtr
head
Ω
Ω
Ω
Ω
void List::append(elemType item){ // Prepare a new node nodeType *newNode; // pointer to new node nodeType *temPtr; // To move across list newNode = new nodeType; // Create new node newNode->data = item; // Store data newNode->next = NULL;
// With empty list, make new node the first if (head == NULL) head = newNode; else{ . . .
append (item) Operation
. . . // Start at head of list temPtr = head; // Find the last node while (temPtr->next != NULL){ temPtr = temPtr->next; }
// Insert node at end temPtr->next = newNode; }}
insertInOrder(item) Operation
temPtr newNode
A) Declare temPtr, prevPtr, and newNode pointers
B) Create a new node, insert data
newNode xxx5 temPtr ΩΩ
head Ω2 4 6 8
prevPtr
insertInOrder(item) OperationC) If list empty, make new node the first
D) Otherwise, set temPtr to head, prevPtr to NULL
temPtr
head Ω
newNode xxx5 Ω
prevPtr Ω
head Ω2 4 6 8
insertInOrder(item) OperationE) Skip all nodes whose data value < item. A pointer to the previous node is necessary in order to link a new node.
5
temPtrprevPtr
head Ω2 4 6 8
insertInOrder(item) OperationF) Link the new node to the one following it in order.
G) Link the previous node to the new node.
temPtrprevPtr
head Ω2 4 6 8
newNode xxx5 Ω
Your Turn
Sketch a diagram of linked list with 5 nodes. The list is pointed to by head. Write an algorithm to print the data content of each node.
print() Operation (List traversal)
temPtr
A) Declare temPtr
B) temPtr head (Why not let head move down the list?)
head Ω2 4 6 8
prevPtr
print() Operation (cont.)
C) While not at end of list, print current item.
while (temPtr != NULL) { cout << temPtr->data << ‘ ‘;
D) Move the temPtr.
temPtr = temPtr->next; }
head Ω2 4 6 8
deleteNode(item) Operation
temPtr
A) Declare temPtr, prevPtr pointers (Why 2 ptrs?)
B) If list is empty, done.
head Ω2 4 6 8
prevPtr
item 6
deleteNode(item) OperationC) If first node is to be deleted (if (item == headdata):
1. 1. Let temPtr = headnext
2. 2. Delete the first node (delete head;)
3. 3. Let head = temPtr
temPtr
head Ω4 6 8
temPtr
head Ω2 4 6 8
deleteNode(item) OperationD) Otherwise, find the node to be deleted.
• Set temPtr to head
• While (temPtr != NULL && tempPtrdata != item)
1. Set prevPtr = temPtr
2. temPtr = temPtrnext
temPtrprevPtr
head Ω2 4 6 8
deleteNode(item) Operation
The loop is exited for one of 2 reasons:1. temPtr == NULL2. temPtr->data == item
If (temPtr != NULL) Let prevPtrnext = temPtrnext Delete node pointed to by temPt
temPtrprevPtr
head Ω2 4
6
8
clear() Operation
A)A) Traverse the list, deleting each node.
B) B) Let head point to NULL.
temPtr
Ωhead 2 4 6 8
clear() Operation (cont)
temPtr1
Ωhead 2 4 6 8
Let temPtr1 point to head.While (temPtr1 != NULL) Let temPtr2 point to temPtr1->next delete current node (pointed to by temPtr1) Let temPtr point to temPtr2
Let head point to NULL
temPtr2
Other Forms of Linked List
Linked list with a header node
Advantages
Can simplify algorithms for basic insertion and deletion, since even an empty list has a node.
Can contain global values, like current node count, smallest value, etc.
head 2 4 6 Ω
deleteNode(item)Suppose:
temPtr points to a node to be deleted prevPtr points to a node before that node A list with a single node is not a special case
prevPtr = temPtr.next;
5
head 2
prevPtr temPtr
4 6 Ω
Circular Linked List
Last pointer, instead of ending the list, points to the first one.
In fact, head and back has little meaningCan process list from anywhere.May arbitrarily designate one node as current,
and use a pointer to process list.
current
Traversing Circular Linked List
current
if (current != NULL){ temPtr = current; do { cout << temPtr->data << endl; temPtr = tempPtr->next; }while (temPtr != current);}
Doubly Linked List (Data Structure)
struct nodeType { elemType data;
nodeType *next; // ptr to next node nodeType *prev; // ptr to previous node};
nodeType *head;nodeType *back;
Doubly Linked List
Each node has two pointersTo the next nodeTo the previous node
Allows for list processing in either direction with equal ease.
Ω
head
Ω
back
append(item)
head
back
A) Prepare a new node.
123
B) If list is empty, head and back point to new node
ΩΩ
123ΩΩ
temPtr
temPtr
append(item)
C) Else, insert at back
• Backnext = temPtr
• temPtrprev = back
• Back = temPtr
Ω
head
Ω
back 123
temPtr
Ω
Append(item)void Dlist::append(elemType item){ // Crreate a new node nodeType *newNode; newNode = new nodeType; newNode->data = item; newNode->next = NULL; newNode->prev = NULL;
if (head == NULL){ head = newNode; back = newNode; } else { back->next = newNode; newNode->prev = back; back = newNode; }}