From charlesreid1

(Created page with "Linked Lists: Linked lists are a data structure whereby each element of a list is stored in a structure of linked wrapper objects that simply hold a data value and point to...")
 
No edit summary
 
(13 intermediate revisions by the same user not shown)
Line 1: Line 1:
Linked Lists:
==List Interfaces in Java API==


Linked lists are a data structure whereby each element of a list is stored in a structure of linked wrapper objects that simply hold a data value and point to neighbor items. The list is an object that contains only one reference to the beginning of the list. Remaining elements must be obtained from the items in the list themselves.
===List ADT===


The linked list structure can be implemented as a singly-linked list or a doubly-linked list. A singly linked list means each list node points only to the next node (or a null pointer if the end of the list). A doubly linked list means each list node points at the prior node as well as the next node.
The List interface - adding <code>implements List<E></code> to a class - has quite a few methods that need to be defined. This makes a data collection capable of being treated as a Collections object.


The purpose of using linked lists is that certain operations become much faster (for example, adding elements to the front or back of a list) when using a linked object data structure than they would be using an array-based data structure, which would need to constantly shift or resize elements.
The full list is here: List interface class abstract methods: https://docs.oracle.com/javase/8/docs/api/java/util/List.html


==Why Linked Lists==
Link to implementations of various Linked Lists on on git.charlesreid1.com: https://git.charlesreid1.com/cs/java/src/master/lists/linked-lists


Linked lists are a basic data structure, and the idea is a simple one, on the surface. These are excellent for testing understanding, however, because a Linked List takes practice and experience to implement correctly. This can separate the student who says "Let me try this concept out first..." and knows how to practice, from a student who says "Yes yes, I understand, it's very easy, now on to the next topic" and has not actually sat down to implement any of the basics, let alone the more advanced stuff.
===LinkedList ADT===
 
The linked list abstract data type provides the following methods:
* size
* isEmpty
* first
* last
* addFirst
* addLast
* removeFirst
 
Furthermore, convenience methods can be added, like:
* add
* remove
* remove(i)
* removeFirst
* removeLast
 
See Java API for LinkedList class: https://docs.oracle.com/javase/8/docs/api/java/util/LinkedList.html
 
==Code Implementation==
 
===Singly Linked List===
 
A basic singly linked list that forces the data type to be an integer is defined in IntList.java: https://git.charlesreid1.com/cs/java/src/master/lists/linked-lists/IntList.java
 
It takes quite a bit of work to get everything functioning correctly - particularly with remove operations. None of the difficulty is in the concept. It is all in the details.
 
Practice, review the details, document learning process/patterns/mistakes here: https://git.charlesreid1.com/cs/java/src/master/lists/linked-lists
 
===Generic Type Linked List===
 
The next phase of implementing a linked list is to make it type-generic, so that it can utilize the diamond notation of the Java Collections library and the type protection it requires.
 
Typed linked list TLinkedList<E> class: https://git.charlesreid1.com/cs/java/src/master/lists/linked-lists/TLinkedList.java
 
===Circular Linked List===
 
A linked list organized in a circular fashion, that can be expanded but that is efficient in its re-use of space.
 
Circular linked list CLinkedList<E> class: https://git.charlesreid1.com/cs/java/src/master/lists/linked-lists/CLinkedList.java
 
===Doubly Linked List===
 
Implementation of a linked list that stores a reference to a header and trailer node, "bumper nodes" that make the implementation of various algorithms easier.
 
=Questions=
 
 
==Goodrich et al Data Structures in Java Chapter 3 questions==
 
Note that Goodrich spends the first few chapters of the Java book focusing on linked lists and link-based data structures, while in the Python book the emphasis is on array lists and array-based data structures.
 
Questions about Java arrays and lists:
 
===Tail Pointer===
 
Question R-3.5) SinglyLinkedList sets the tail field to null when deleting last node of a list. What if those lines were removed? Would class still work, and why or why not?
 
Class would no longer work properly - if tail pointer is not null, will not be able to use fact that tail pointer points at null for end of list. Tail pointer is never reset to null, so dangling node will always be a dangling node until tail is explicitly reset to something else. (Some functionality may not be affected - but it depends entirely on the order of operations.)
 
===Second to last===
 
'''Question R-3.6) Find second to last node in singly linked list, where last node is indicated by having a null reference.'''
 
To find second to last node, you're checking two nodes ahead:
 
<pre>
if(size==0 || size==1) {
    // no second to last node
}
 
Node runner = this.head;
while(runner.getNext().getNext() != null) {
    runner = runner.getNext();
}
// Now runner points to the node that points to the null node
// (i.e., runner points to the second-to-last node.)
</pre>
 
===Midpoint===
 
Finding the midpoint of a singly linked list:
* Naive solution: traverse the list once, counting along the way, then traverse the list a second time
* But, why not count twice if we can
* Two steps with the runner, one step with the head. etc..


==The Gist of Linked Lists==
Finding the midpoint of a doubly linked list:
* In the case of an odd number of nodes, iterating head forward and tail backward will eventually have head and tail equal - pointing to same node
* In the case of an even number of nodes, the head and tail are passing ships in the night - so we need to check if head.next == tail


Questions about Linked Lists require handling a number of different assumptions, questions, and possible interfaces. Which one you implement depends on the problem and specifications. However, "Linked List" should immediately call to mind the methods in a List ADT (abstract data type) and by extension the methods in a LinkedList ADT.
===Implementing the Size Method===


They are mainly the same, but their level of detail depends on the features of the list.
'''Question R-3.9) Give an implementation of the size() method for the SingularlyLinkedList class, assuming that we did not maintain size as an instance variable.'''


==List ADT==
<pre>
if(isEmpty()) {
    throws new Empty();
}
int count = 1;
Node runner = head;
while(runner.getNext()!=null) {
    count++;
    runner = runner.getNext();
}
</pre>


===LinkedList ADT===
'''Question R-3.10) Give an implementation of the size() method for the DoublyLinkedList class, assuming that we did not maintain size as an instance variable.'''
 
<pre>
if(isEmpty()) {
    throws new Empty();
}
int count = 1;
Node hrunner = head;
Node trunner = tail;
while(hrunner!=trunner && hrunner.getNext()!=trunner) {
    count++; count++;
    hrunner = hrunner.getNext();
    trunner = trunner.getNext();
}
if(hrunner!=trunner) {
    // the pointers don't match - even number of elements
    count--;
}
 
// This handles the empty DLL, the one-element DLL, the two-element DLL, the three-element DLL
</pre>
 
'''Question R-3.11) Give an implementation of the size() method for the CircularlyLinkedList class, assuming that we did not maintain size as an instance variable.'''
 
 
 
===Rotate===
 
Question R-3.12) Implement a rotate() method in the SinglyLinkedList class, which has semantics equal to addLast(removeFirst()) but which does not create any new node.
 
 
 
 
=Flags=


The linked list abstract data type provides the following methods:
[[Category:LinkedLists]]
[[Category:Java]]
{{DataStructuresFlag}}

Latest revision as of 00:09, 17 March 2019

List Interfaces in Java API

List ADT

The List interface - adding implements List<E> to a class - has quite a few methods that need to be defined. This makes a data collection capable of being treated as a Collections object.

The full list is here: List interface class abstract methods: https://docs.oracle.com/javase/8/docs/api/java/util/List.html

Link to implementations of various Linked Lists on on git.charlesreid1.com: https://git.charlesreid1.com/cs/java/src/master/lists/linked-lists

LinkedList ADT

The linked list abstract data type provides the following methods:

  • size
  • isEmpty
  • first
  • last
  • addFirst
  • addLast
  • removeFirst

Furthermore, convenience methods can be added, like:

  • add
  • remove
  • remove(i)
  • removeFirst
  • removeLast

See Java API for LinkedList class: https://docs.oracle.com/javase/8/docs/api/java/util/LinkedList.html

Code Implementation

Singly Linked List

A basic singly linked list that forces the data type to be an integer is defined in IntList.java: https://git.charlesreid1.com/cs/java/src/master/lists/linked-lists/IntList.java

It takes quite a bit of work to get everything functioning correctly - particularly with remove operations. None of the difficulty is in the concept. It is all in the details.

Practice, review the details, document learning process/patterns/mistakes here: https://git.charlesreid1.com/cs/java/src/master/lists/linked-lists

Generic Type Linked List

The next phase of implementing a linked list is to make it type-generic, so that it can utilize the diamond notation of the Java Collections library and the type protection it requires.

Typed linked list TLinkedList<E> class: https://git.charlesreid1.com/cs/java/src/master/lists/linked-lists/TLinkedList.java

Circular Linked List

A linked list organized in a circular fashion, that can be expanded but that is efficient in its re-use of space.

Circular linked list CLinkedList<E> class: https://git.charlesreid1.com/cs/java/src/master/lists/linked-lists/CLinkedList.java

Doubly Linked List

Implementation of a linked list that stores a reference to a header and trailer node, "bumper nodes" that make the implementation of various algorithms easier.

Questions

Goodrich et al Data Structures in Java Chapter 3 questions

Note that Goodrich spends the first few chapters of the Java book focusing on linked lists and link-based data structures, while in the Python book the emphasis is on array lists and array-based data structures.

Questions about Java arrays and lists:

Tail Pointer

Question R-3.5) SinglyLinkedList sets the tail field to null when deleting last node of a list. What if those lines were removed? Would class still work, and why or why not?

Class would no longer work properly - if tail pointer is not null, will not be able to use fact that tail pointer points at null for end of list. Tail pointer is never reset to null, so dangling node will always be a dangling node until tail is explicitly reset to something else. (Some functionality may not be affected - but it depends entirely on the order of operations.)

Second to last

Question R-3.6) Find second to last node in singly linked list, where last node is indicated by having a null reference.

To find second to last node, you're checking two nodes ahead:

if(size==0 || size==1) { 
    // no second to last node
}

Node runner = this.head;
while(runner.getNext().getNext() != null) { 
    runner = runner.getNext();
}
// Now runner points to the node that points to the null node
// (i.e., runner points to the second-to-last node.)

Midpoint

Finding the midpoint of a singly linked list:

  • Naive solution: traverse the list once, counting along the way, then traverse the list a second time
  • But, why not count twice if we can
  • Two steps with the runner, one step with the head. etc..

Finding the midpoint of a doubly linked list:

  • In the case of an odd number of nodes, iterating head forward and tail backward will eventually have head and tail equal - pointing to same node
  • In the case of an even number of nodes, the head and tail are passing ships in the night - so we need to check if head.next == tail

Implementing the Size Method

Question R-3.9) Give an implementation of the size() method for the SingularlyLinkedList class, assuming that we did not maintain size as an instance variable.

if(isEmpty()) {
    throws new Empty();
}
int count = 1;
Node runner = head;
while(runner.getNext()!=null) { 
    count++;
    runner = runner.getNext();
}

Question R-3.10) Give an implementation of the size() method for the DoublyLinkedList class, assuming that we did not maintain size as an instance variable.

if(isEmpty()) {
    throws new Empty();
}
int count = 1;
Node hrunner = head;
Node trunner = tail;
while(hrunner!=trunner && hrunner.getNext()!=trunner) {
    count++; count++;
    hrunner = hrunner.getNext();
    trunner = trunner.getNext();
}
if(hrunner!=trunner) {
    // the pointers don't match - even number of elements
    count--;
}

// This handles the empty DLL, the one-element DLL, the two-element DLL, the three-element DLL

Question R-3.11) Give an implementation of the size() method for the CircularlyLinkedList class, assuming that we did not maintain size as an instance variable.


Rotate

Question R-3.12) Implement a rotate() method in the SinglyLinkedList class, which has semantics equal to addLast(removeFirst()) but which does not create any new node.



Flags