ITSC 2214 Week 6
If you have a double-linked list and you remove the last item in the list, how many pointers are updated (not including the temp pointer to the element)?
2
Remove singly-linked list head node (special case):
> If curNode is null, the algorithm points sucNode to the head node's next node, and points the list's head pointer to sucNode. > If sucNode is null, the only list node was removed, so the list's tail pointer is pointed to null (indicating the list is now empty).
Remove node after curNode in singly-linked list:
> If curNode's next pointer is not null (a node after curNode exists), the algorithm points sucNode to the node after curNode's next node. > Then curNode's next pointer is pointed to sucNode. If sucNode is null, the list's tail node was removed, so the algorithm points the list's tail pointer to curNode (the new tail node).
LinkedList vs. ArrayList
> LinkedList and ArrayList are ADTs implementing the List interface. > Although both LinkedList and ArrayList implement a List, a programmer should select the implementation that is appropriate for the intended task. > A LinkedList typically provides faster element insertion and removal at the list's ends (and middle if using ListIterator), whereas an ArrayList offers faster positional access with indices.
A common approach for implementing a linked list is using two data structures:
> List data structure > List node data structure
List
> interface defined within the Java Collections Framework defines a Collection of ordered elements, i.e., a sequence. > The List interface supports methods for adding, modifying, and removing elements.
List data structure
A list data structure, called a header node, is a data structure containing the list's head and tail, and may also include additional information such as the list's size
Which of the following operations are more efficient when using a linked list than with an array list?
Add item to beginning of list (prepend). Insert item into middle of list.
Which operations below are standard operations you might want to perform with a list collection? Assume the list is not sorted
Add to front Remove from back Peek at front Remove (element) Peek at back Add after (element) Remove from front Add to back
LinkedList.add(index, newElement)
Adds newElement to the List at the specified index. Indices of the elements previously at that specified index and higher are increased by one. List's size is increased by one.
LinkedList.add(newElement)
Adds newElement to the end of the List. List's size is increased by one.
ListIterator.add(newElement)
Adds the newElement between the next and previous elements and moves the ListIterator after newElement.
Imagine you want to keep a list of customer leads for your business. You want them sorted by most recent contact date, which is a property in the CustomerLead class. You are adding new customer leads every day. You also need to remove customer leads when it becomes apparent that the customer is not interested in your product. You want to be able to move customers to one end of the list when you recontact them. You want to be able to do a lot at the other end of the list where there are customers that haven't been contacted recently. What type of list should you use?
Doubly-linked list, sorted
node
Each item in a list ADT
A linked list must have a header node
False > A header node is optional. A programmer can alternatively use variables to maintain a list's head and tail, or size. Header nodes are a convenient structure for managing a list's head and tail.
Remove operation, Removing list's head node:
If curNode points to the list's head node, the algorithm points the list's head pointer to the successor node
Remove operation, Removing list's tail node:
If curNode points to the list's tail node, the algorithm points the list's tail pointer to the predecessor node
Insert in middle of doubly-linked list:
If the list's head pointer is not null (list is not empty) and curNode does not point to the list's tail node, the algorithm updates the current, new, and successor nodes' next and previous pointers to achieve the ordering {curNode newNode sucNode}, which requires four pointer updates: point the new node's next pointer to sucNode, point the new node's previous pointer to curNode, point curNode's next pointer to the new node, and point sucNode's previous pointer to the new node.
Insert after doubly-linked list tail node:
If the list's head pointer is not null (list is not empty) and curNode points to the list's tail node, the new node is inserted after the tail node. The algorithm points the tail node's next pointer to the new node, points the new node's previous pointer to the list's tail node, and then points the list's tail pointer to the new node.
Insert in middle of singly-linked list:
If the list's head pointer is not null (list not empty) and curNode does not point to the list's tail node, the algorithm points the new node's next pointer to curNode's next node, and then points curNode's next pointer to the new node.
Insert after singly-linked list tail node:
If the list's head pointer is not null (list not empty) and curNode points to the list's tail node, the algorithm points the tail node's next pointer and the list's tail pointer to the new node.
Prepend to non-empty singly-linked list:
If the list's head pointer is not null (not empty), the algorithm points the new node's next pointer to the head node, and then points the list's head pointer to the new node.
Prepend to non-empty doubly-linked list:
If the list's head pointer is not null (not empty), the algorithm points the new node's next pointer to the list's head node, points the list head node's previous pointer to the new node, and then points the list's head pointer to the new node
Append to non-empty singly-linked list:
If the list's head pointer is not null (not empty), the algorithm points the tail node's next pointer and the list's tail pointer to the new node
Append to non-empty doubly-linked list:
If the list's head pointer is not null (not empty), the algorithm points the tail node's pointer to the new node, points the new node's previous pointer to the list's tail node, and points the list's tail pointer to the new node.
Append to empty singly-linked list:
If the list's head pointer is null (empty), the algorithm points the list's head and tail pointers to the new nod
Prepend to empty doubly-linked list:
If the list's head pointer is null (empty), the algorithm points the list's head and tail pointers to the new node
Append to empty doubly-linked list:
If the list's head pointer is null (empty), the algorithm points the list's head and tail pointers to the new node.
Prepend to empty singly-linked list:
If the list's head pointer is null (empty), the algorithm points the list's head and tail pointers to the new node.
Insert as first node in doubly-linked list:
If the list's head pointer is null (list is empty), the algorithm points the list's head and tail pointers to the new node.
Insert as singly-linked list first node:
If the list's head pointer is null, the algorithm points the list's head and tail pointers to the new node.
Remove operation, Predecessor exists:
If the predecessor node pointer is not null (predecessor exists), the algorithm points the predecessor's next pointer to the successor node
Remove operation, Successor exists:
If the successor node pointer is not null (successor exists), the algorithm points the successor's previous pointer to the predecessor node
InsertAfter(list, w, x)
Inserts x after w
Append(list, x)
Inserts x at end of list
Prepend(list, x)
Inserts x at start of list
LinkedList creation code:
LinkedList<T> linkedList = new LinkedList<T>();
The addLast(Object) operation in a list implemented with an array has Big O complexity of:
O(1)
The add(int, Object) operation in a list with a linked implementation has what level of complexity?
O(n)
The complexity of a set(index, Object) operation using a linked list implementation of a list is:
O(n)
What would be the complexity of the size() method for the linked implementation of a list, if there were no count variable?
O(n)
Print(list)
Prints list's items in order
PrintReverse(list)
Prints list's items in reverse order
LinkedList.remove(index)
Removes element at specified index. Indices for elements from higher positions are decreased by one. List size is decreased by one. Returns reference to element removed from List.
ListIterator.remove()
Removes the element returned by the prior call to next() or previous(). Fails if used more than once per call to next() or previous(). Fails if add() has already been called since the last call to next() or previous().
LinkedList.remove(existingElement)
Removes the first occurrence of an element which is equal to existingElement. Indices for elements from higher positions are decreased by one. List size is decreased by one. Returns true if specified element was found and removed.
Remove(list, x)
Removes x
LinkedList.set(index, newElement)
Replaces element at specified index with newElement. Returns element previously at specified index.
ListIterator.set(newElement)
Replaces the element returned by the prior call next() or previous() with newElement.
LinkedList.get(index)
Returns element at specified index.
Search(list, x)
Returns item if found, else returns null
ListIterator.nextIndex()
Returns the index of the next element.
ListIterator.previousIndex()
Returns the index of the previous element.
ListIterator.next()
Returns the next element in the List and moves the ListIterator after that element.
LinkedList.size()
Returns the number of elements in the List.
ListIterator.previous()
Returns the previous element in the List and moves the ListIterator before that element.
ListIterator.hasNext()
Returns true if ListIterator has a next element. Otherwise, returns false.
ListIterator.hasPrevious()
Returns true if ListIterator has a previous element. Otherwise, returns false.
Imagine you want to keep a list of donors for a fundraising event and you want to be able to group donors by the amounts they have donated for various purposes. You are adding new donors all the time. What type of list should you use?
Singly-Linked, Sorted List
Sort(list)
Sorts the lists items in ascending order
List node data structure
The list node data structure maintains the data for each list element, including the element's data and pointers to the other list element
A header node can have additional information besides the head and tail pointers.
True > A list header commonly stores the list size and other data associated with the list itself and not the list nodes.
A linked list has O(n) space complexity, whether a header node is used or not.
True > If a header node is used, O(1) space is needed for the single header node. O(n) + O(1) = O(n).
What differentiates lists from queues?
You can add and retrieve items from the middle.
list
a common ADT for holding ordered data, having operations like append a data item, remove a data item, search whether a data item exists, and print the list
header node
a data structure containing the list's head and tail, and may also include additional information such as the list's size
singly-linked list
a data structure for implementing a list ADT, where each node has data and a pointer to the next node
doubly-linked list
a data structure for implementing a list ADT, where each node has data, a pointer to the next node, and a pointer to the previous node > first node is called the head, and the last node the tail > typically points to the first node and the last node
abstract data type
a data type described by pre-defined user operations, such as "insert data at rear," without indicating how each operation is implemented
LinkedList
an ADT implemented as a generic class that supports different types of elements
ListIterator
an object that points to a location in a List and provides methods to access an element and advance the ListIterator to the next position in the list
Assume you are adding an item 'F' to the end of this list. You have created a new linear node called temp that contains a pointer to 'F'. What lines of code appropriately update the list?
back.setNext(temp); back = temp; numNodes++;
import LinkedList code:
import java.util.LinkedList;
import ListIterator code:
import java.util.ListIterator;
InsertAfter operation for a doubly-linked list
inserts the new node after a provided existing list node
the InsertAfter operation for a singly-linked list ___
inserts the new node after a provided existing list node
Append operation for a doubly-linked list
inserts the new node after the list's tail node
Append operation for a singly-linked list
inserts the new node after the list's tail node
the Prepend operation for a singly-linked list ___
inserts the new node before the list's head node
Prepend operation of a doubly-linked list
inserts the new node before the list's head node and points the head pointer to the new node.
Which operations below are standard operations you might want to perform with a list collection that is sorted?
remove from back remove from front remove (element) add peek at back peek at front
Remove operation for a doubly-linked list
removes a provided existing list node
Given a specified existing node in a singly-linked list, the RemoveAfter operation ___
removes the node after the specified list node
search algorithm
returns the first node whose data matches the key, or returns null if a matching node was not found
head
singly-linked list's first node
tail
singly-linked list's last node
What scenarios should be considered 'special or edge cases' when creating a method to add a node to a sorted Linked List? Hint: special cases with lists usually involve changing the head/tail references.
the list is empty the node needs to go at the front of the list the node needs to go at the end of the list
list traversal algorithm:
visits all nodes in the list once and performs an operation on each node
reverse traversal algorithm:
visits all nodes starting with the list's tail node and ending after visiting the list's head node > only supported by doubly-linked list
data structure
way of organizing data, commonly used to implement an abstract data type (ADT), and often involving arrays or pointers
to interact with a LinkedList by index ___
you have to iterate through each reference from 0 to the index, since the next reference needs to be checked to find the next item in the LinkedList