Title: Data Structures, Lists, Linked Lists
1Data Structures, Lists, Linked Lists
- Data Structures
- The premise you are storing large amounts of
information in a collection - We have already discussed how usage patterns
affect which kind of data structure is
appropriate - Want duplicates ignored? Use a Set rather than a
List - Elements in some order? Use a List rather than a
Set - Need only key/value lookup? Use a Map rather
than a Set or List - These collection types only specify interfaces,
not implementation - they determine what functionality you get, now
how efficient it is to implement the operations - Now we move to the next level what is the
appropriate backing store to use - which is only an efficiency issue the
functionality (interface) is fixed - There are typically certain operations you intend
to perform commonly on the collection, and
certain other operations you do not intend to
perform commonly. For example - add to the end of the collection, but never
delete - add to the end of the collection, but never to
the middle - add to the front of the collection
- only delete from the end of the collection
- all items are added at first, then lots of
lookups - Generally we talk about adds, deletes, and finds,
how often they occur, and any special
characteristics of each (e.g. only at beginning,
only at end)
2List Interface
- The List Interface is not a data structure, in
that it doesn't commit to any implementation.
What it commits to is - Positional access to and manipulation of data
- get and set the ith element
- insert before or delete the ith element
- return the first index of a matching object
- More general operators inherited from Collection
- add an element somewhere
- delete a matching element
- clear(), isEmpty(), size()
3Implementations of the List Interface
- Java provides ArrayList and LinkedList
- ArrayList is backed by an array
- we will see how LinkedList stores its elements
- These class do implement data structures, and
each will implement some operations faster than
(and others slower than) the alternative. - Users of these classes have to commit to an
implementation, and this decision has to be made
on the basis of efficiency (since functionally
they are identical). Documentation will discuss
these issues - ArrayList "The size, isEmpty, get, set,
iterator, and listIterator operations run in
constant time. The add operation runs in
amortized constant time, that is, adding n
elements requires O(n) time. All of the other
operations run in linear time (roughly speaking).
The constant factor is low compared to that for
the LinkedList implementation."
4The ArrayList Implementation
- Using an array to implement ArrayList. Main
issues are - how to insert into the middle and remove from the
middle - how to expand the array as objects are added
- maybe how to contract the array as objects are
removed, but nobody seems to do this in practice - Instead of implementing the full List interface,
we will do the following - Along with the constructors for ArrayList
- new ArrayList() // Create a list with initial
capacity 10 - new ArrayList(int initialCapacity)
interface MiniList boolean add(Object
element, int index) Object removeFirst(Object
element) Object get(int index) Object
set(int index, Object newElement) void
clear() int size() Iterator iterator()
5Summary
- Efficient operations
- insert at end
- remove from end
- clear
- get and set at index
- most generally, an array is best for fixed sizes
-- or at least hard maximum -- and positional
access - Inefficient operations
- insert and remove from middle or beginning
- insert anywhere, if it involves resizing the
array (and hence an array copy)
6The LinkedList
- This is an extremely common data structure,
especially for situations where - inserts and removes are common everywhere on the
list - you need iterator access but not positional access
A linked list of size 2 two "list nodes" that
need not be contiguous. First node "points to"
the second node, but is not "next to" the second
node.
String2
"hello"
"world"
null
An array of length 2 two contiguous
references to data objects. (No "space" between
the first and second element.)
"hello"
"world"
7Linked List Terminology
"List nodes" ListNode There is one for each
element in the list. Two fields, data and
next. Data is Object, or String, or Student, or
whatever you declare it to be. Next field is of
type ListNode
"List head" LinkedList There is one per list
regardless of size. It points to the first "list
node." Single field head, which is of type
ListNode
LinkedList
null
"hello"
(some other object)
8Some Example Pictures (and Shorthands)
-- Sometimes we pretend as though the list can
hold integers -- Sometimes we use a generic "end
of list" symbol instead of null
?
1
82
-3
-- Sometimes we pretend as though the data value
is "inside of" the list node
?
"hi"
"mom"
-- Sometimes we pretend as though there is no
head node
?
-4
12
199
9Inserts, Deletes, Finds, and Traversals in Linked
Lists
- Insert a new object into the list
- at the beginning
- in the middle
- at the end
- Delete an object from the list
- at the beginning
- deleting the last element
- in the middle
- at the end
- Find an object in the list
- by equality
- by position
10Basic Insertion
99
"Insert this value after this node in the list"
?
1
82
-3
11Insertion 1-2-3-4
- Create a new list node
- Insert the new data value in it
(Insert after here)
99
?
1
82
-3
12Insertion 3-4
- Point the new node to the "next" pointer of the
insertion point - Adjust the "next" pointer of the insertion point
99
?
1
82
-3
13Special Case Insert at the Beginning
(Insert here)
-129
?
1
82
-3
14Insert at Beginning Same Process
-129
?
1
82
-3
15Basic Deletion
"Remove this node from the list"
?
1
82
-3
16The Key to Deletion Find the Predecessor
Predecessor
"Remove this node from the list"
?
1
82
-3
17Splice The Predecessor Past the Deleted Node
Predecessor
?
1
82
-3
(Orphaned node)
18Finding and ChangingValues, and Traversing
- Positional access
- get(index i) set(index i)
- indexOf(Object)
- Find by value
- contains(Object o)
- Traversal by iterator