460 likes | 695 Views
Linked List. Ω. head. Linked List. Linked List Is a series of connected nodes, where each node is a data structure with data and pointer(s) Advantages over array implementation Can grow and shrink in size, with no upper limit Fast insertion and deletion. Node.
E N D
Ω head Linked List • Linked List • Is a series of connected nodes, where each node is a data structure with data and pointer(s) • Advantages over array implementation • Can grow and shrink in size, with no upper limit • Fast insertion and deletion
Node struct nodeType { elemType data; nodeType *next; } nodeType *head; head pointer to node data Note the self-referencing form of the data structure. Note the recursive form of the data structure. Note the recursive form of the data structure
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; };
head Ω List() Operation (Constructor) In list.cpp, assume the following directive: #define EMPTY -99999 // empty value A) Let head point to NULL eeeeee now eieiie List(){ head = NULL;} List::List() { head = NULL;} Ω
xxx Ω head insertAtFront(item) Operation A) Declare newNode pointer newNode B) Create a new node, insert data Ω Ω newNode 123
xxx insertAtFront (item) Operation C) Insert new node at front Ω head newNode 123 Ω
insertAtFront(item) Operation 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 • 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.
Ω head elemType removeFromFront() Operation A) Declare temPtr temPtr B) If (isEmpty()). . . return EMPTY Ω
temPtr Ω Ω head elemType removeFromFront() Operation Else . . . C) Let temPtr point to where head points to: temPtr head
Ω head temPtr elemType removeFromFront() Operation D) Let head point to the 2nd Node. E) Save the item removed. Ω head temPtr elemType result = temPtr->data;
Ω head temPtr elemType removeFromFront() Operation F) Delete the node. delete temPtr; G) Return the item removed. return result;
elemType removeFromFront() Operation elemType List::removeFromFront item){ if (isEmpty()) return NULL; nodePtr *temPtr; temPtr = head; head = head->next; elemType result = temPtr->data; delete temPtr; return result;}
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.
xxx Ω head append(item) Operation A) Declare temPtr, newNode pointers temPtr newNode B) Create a new node, insert data Ω Ω newNode 123 temPtr
xxx Ω head temPtr append(item) Operation C) Iflistempty,makenewnodethefirst head Ω Ω 123 newNode D)Otherwise,find the last node
xxx append (item) Operation While temPtr.next != Null, move temPtr Ω head Ω temPtr E) Insert new node at end Ω head temPtr 123 Ω Ω newNode
append (item) Operation 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{ . . .
. . . // 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; } }
xxx insertInOrder(item) Operation Ω head 2 4 6 8 A) Declare temPtr, prevPtr, and newNode pointers temPtr prevPtr newNode B) Create a new node, insert data Ω 5 Ω newNode temPtr
xxx insertInOrder(item) Operation C) If list empty, make new node the first head Ω Ω 5 newNode D) Otherwise, set temPtr to head, prevPtr to NULL Ω head 2 4 6 8 Ω temPtr prevPtr
insertInOrder(item) Operation E) Skip all nodes whose data value < item. A pointer to the previous node is necessary in order to link a new node. 5 Ω head 2 4 6 8 temPtr prevPtr
xxx insertInOrder(item) Operation F) Link the new node to the one following it in order. G) Link the previous node to the new node. Ω head 2 4 6 8 temPtr prevPtr 5 Ω newNode
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) Ω head 2 4 6 8 A) Declare temPtr temPtr prevPtr B) temPtr head (Why not let head move down the list?)
print() Operation (cont.) Ω head 2 4 6 8 C) While not at end of list, print current item. while (temPtr != NULL) { cout << temPtr->data << ‘ ‘; D) Move the temPtr. temPtr = temPtr->next; }
deleteNode(item) Operation item 6 Ω head 2 4 6 8 A) Declare temPtr, prevPtr pointers (Why 2 ptrs?) temPtr prevPtr B) If list is empty, done.
deleteNode(item) Operation • C) If first node is to be deleted (if (item == headdata): • 1. Let temPtr = headnext • 2. Delete the first node (delete head;) • 3. Let head = temPtr Ω head 2 4 6 8 temPtr head Ω 4 6 8 temPtr
Ω head 2 4 6 8 deleteNode(item) Operation • D) Otherwise, find the node to be deleted. • Set temPtr to head • While (temPtr != NULL && tempPtrdata != item) • Set prevPtr = temPtr • temPtr = temPtrnext temPtr prevPtr
Ω head 2 4 8 6 prevPtr temPtr 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
head 2 4 6 8 Ω temPtr clear() Operation A) Traverse the list, deleting each node. B) Let head point to NULL.
head 2 4 6 8 clear() Operation (cont) Ω temPtr1 temPtr2 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
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 caseprevPtr = temPtr.next; 5 4 6 Ω head 2 temPtr prevPtr
Circular Linked List • Last pointer, instead of ending the list, points to the first one. • In fact, head and back has little meaning • Can process list from anywhere. • May arbitrarily designate one node as current, and use a pointer to process list. current
Traversing Circular Linked List if (current != NULL){ temPtr = current; do { cout << temPtr->data << endl; temPtr = tempPtr->next; }while (temPtr != current);} 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 pointers • To the next node • To the previous node • Allows for list processing in either direction with equal ease. head Ω Ω back
append(item) A) Prepare a new node. temPtr Ω 123 Ω B) If list is empty, head and back point to new node head temPtr Ω 123 Ω back
head temPtr Ω Ω Ω back 123 append(item) • C) Else, insert at back • Backnext = temPtr • temPtrprev = back • Back = 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; } }