CSE240 Doubly Linked ListsBY GARRETT GUTIERREZ
What is a doubly linked list?A doubly linked list is a list of elements.Each element points to the next element in
the list as well as the previous element in the list.
Why use a doubly linked list over a single linked list?Doubly linked lists allow easy traversal forward
and backward through the list.
How to get started? Create either a struct or an object to represent a node in
the linked list. It has a reference to the previous and next items in the
linked list. Use a tail pointer, in addition to a head pointer.struct node{
int id;char* name; // A pointer, not an arraystruct node* previous; // pointer to previous nodestruct node* next; // pointer to next node in list
};
Q1. What is the size of the node?.(A) 4 bytes(B) 16 bytes(C) more than 16 bytes?(D) The size is unknown at
compilation.Think: How to obtain memory for name?
Insertion: Case by Case Inserting an element into a doubly linked list
is very similar to inserting an element into a singly linked list.
Additionally, just make the previous pointer point to the previous item in the linked list.
There are three cases for sorted insert:1. Add at the beginning2. Add at an arbitrary location3. Add to the end
Case 0: The linked list is empty
Make the new node the head
Set previous and next to NULL of head
Set tail to head
head NULL
NULL
head nameidprevious next
if (head == NULL){
head = newNode;head->next = NULL;head->previous = NULL;tail = head;return;
}tail
NULL
Q2. When is the tail pointer equals to the head pointer? Select all that apply.(A) When the list is empty(B) When there is one node only(C) When there are more than one node(D) They never equal.
Case 1: Add element to beginning
Set newNode->next to head->nextSet head->previous to newNodeSet head to the newNodeMake the newNode previous NULL
head
NULLif (strcmp(newNode->name, head->name) < 0){newNode->next = head;head->previous = newNode;head = newNode;head->previous = NULL;return;}
nameidprevious next
nameidprevious next
nameidprevious next
head
NULL
newNode The old headNULL
NULL
Q3. Which node’s previous pointer is NULL?(A) The first node(B) The second node(C) The last node(D) No node.
Case 2: Add at an arbitrary locationUse a iterator pointer and a follower
pointer.follower always is one element behind
iteratorstruct node* iterator = head;struct node* follower = iterator;
Case 2: Add to an arbitrary location
Set newNode->next to iteratorSet iterator->previous to newNodeSet the newNode->previous to followerSet follower->next to newNode
head nameidprevious next
nameidprevious next
NULL
nameidprevious nextnewNode
follower iterator
NULL
Case 3: Add to the endGo through the entire list until iterator is
NULL
Set follower->next to newNodeSet newNode->previous to followerSet newNode->next to NULLSet the tail to newNode
head nameidprevious next
nameidprevious next
NULL
follower iterator
nameidprevious next
tail
NULL
Q4. Is case 3 included in case 2?(A) Yes, case 3 can be simply
removed(B) No. case 3 is not included in
case 2. Explain your answer
Putting it Togetherif (head == NULL) { // Case 0head = newNode;head->next = NULL;head->previous = NULL;tail = head;return;}else { Case 1 if (strcmp(newNode->name, head->name) < 0) {
newNode->next = head;head->previous = newNode;head = newNode;head->previous = NULL;return;
} }};
iterator = head;follower = iterator;while (iterator != NULL) { // Case 2 if (strcmp(newNode->name, iterator->name) < 0) {
newNode->next = iterator;iterator->previous = newNode;newNode->previous = follower;follower->next = newNode;return;
} follower = iterator; iterator = iterator->next;}follower->next = newNode; // Case 3newNode->previous = follower;newNode->next = NULL;tail = newNode;return;
Searching Doubly Linked List: Front
1. Start at the head.2. Go until the iterator is
NULL3. Compare the value of the
iterator with a value.4. If found, return the
element.5. Else, set iterator to next.6. If not found, return NULL.
struct node* iterator = head;while (iterator != NULL){
if (strcmp(iterator->name, token) == 0)
{return iterator;
}iterator = iterator->next;
}printf("The element does not exist.\n\n");return iterator;
Searching Doubly Linked List: Back1. Start at the tail.2. Go until the iterator is NULL3. Compare the value of the
iterator with a value.4. If found, return the element.5. Else, set iterator to previous.6. If not found, return NULL.
struct node* iterator = tail;while (iterator != NULL){
if (strcmp(iterator->name, token) == 0)
{return iterator;
}iterator = iterator->previous;
}printf("The element does not exist.\n\n");return iterator;
Q5. How many lines of code are different when searching forwards and backwards?(A) 0 (B) 1 (C) 2 (D) 4Which lines of code?
Deleting an ElementCase 1: List only has one item
Delete heap memory for nameDelete heap memory for headSet head to NULLSet tail to NULL
NULL
head nameidprevious next
if (head == toDelete && head->next == NULL){
free(head->name);free(head);head = NULL;tail = NULL;return;
}
tail
NULL
Q6. Advance Question: Why do call free twice?free(head->name);free(head);To be discussed in memory management section later.
Continue only if time permit
Deleting an ElementCase 2: Remove head only
Set head to the next item in listDelete memory for nameDelete memory of nodeMake new head->previous NULL
else if (head == toDelete){
head =head ->next;free(toDelete->name);free(toDelete);toDelete = NULL;head->previous =
NULL;return;
}
head nameidprevious next
nameidprevious next
NULL
Old head New headNULL NULL
Case 3: Delete at arbitrary location
Set follower->next to item after iteratorSet item after iterator’s previous to followerDelete memory for nameDelete memory for nodeSet toDelete and iterator to NULL
head nameidprevious next
nameidprevious next
NULLnameidprevious next
toDeletefollower iterator
NULL
Case 3: Delete at the endGo through the entire list until iterator ==
tail
Delete memory for nameDelete memory for nodeSet tail to the followerSet follower->next to NULL
head nameidprevious next
nameidprevious next
follower iterator
nameidprevious next
tail
NULLNULL
tail
if (iterator == tail){
free(iterator->name);free(iterator);tail = follower;follower->next = NULL;return;
}
Putting it all togetherif (head == toDelete && head->next == NULL){
free(toDelete->name);free(toDelete);head = NULL;tail = NULL;return;
}else if (head == toDelete){
head = head->next;free(toDelete->name);free(toDelete);toDelete = NULL;head->previous = NULL;return;
}
while (iterator != NULL){
if (iterator == tail){
free(iterator->name);free(iterator);tail = follower;follower->next = NULL;return;
}else if (strcmp(iterator->name, toDelete->name) == 0){
follower->next = iterator->next;iterator->next->previous = follower;free(iterator->name);free(iterator);iterator = NULL;toDelete = NULL;return;
}follower = iterator;iterator = iterator->next;
}
Printing Doubly Linked List: Front
1. Start at the head.2. Go until the iterator is
NULL3. Print the values of the
node.4. Set iterator to next.
struct node* iterator = head;
while (iterator != NULL){
printf("Name: %s\n”, iterator->name); printf(“ID: %d\n", iterator->id); iterator = iterator->next;
}
Printing Doubly Linked List: Back
1. Start at the tail.2. Go until the iterator is
NULL3. Print the values of the
node.4. Set iterator to previous.
struct node* iterator = tail;
while (iterator != NULL){
printf("Name: %s\n”, iterator->name); printf(“ID: %d\n", iterator->id); iterator = iterator->previous;
}
Top Related