You are on page 1of 46

CSE 326: Data Structures

Part Two: Lists


Henry Kautz
Autumn Quarter 2002
Today
• Abstract versus Concrete Data Types
• List ADT
• Iterators
• Comparing implementations
• Sparse vectors
• Nested lists
– Sparse arrays
– Expressions
Abstract vs. Concrete Data Types
• Abstract Data Type (ADT)
– Mathematical description of an object and the set of
operations on the object
• List, Stack, Tree, Heap, Graph, …
– One ADT may specialize another ADT
– One ADT may implement another ADT
• Concrete Data Type
– Implementation of an ADT using some set of primitive
data types and operations of known complexity
• Primitives: integers, arrays, pointers or references
– Object-oriented programming languages (Java, C++) let
you explicitly define new concrete data types that
correspond to ADT’s.
List ADT
( A1 A2 … An-1 An )
length = n
• Mathematical description: a sequence of items
– Ai precedes Ai+1 for 1  i < n
• Operations
– First() = position
What other operations
– Value(position) = item might be useful?
– Next(position) = position
– Length() = integer
– Insert(item,position)
– Delete(position)
List ADT
( A1 A2 … An-1 An )
length = n
• Mathematical description: a sequence of items
– Ai precedes Ai+1 for 1  i < n
• Operations
– First() = position
What other operations
– Value(position) = item might be useful?
– Next(position) = position
– Kth(integer)=item
Length() = integer
– Insert(item,position) SetKth(item,integer)
– Delete(position) Find(item)=position
Specialization Hierarchy

List
Property: Sequence
First()=pos Value(pos)=item Kth(integer)=item
Next(pos)=pos Length()=integer SetKth(item,integer)
Insert(item,pos) Delete(pos) Find(item)=position

Stack Queue Vector


Property: LIFO Property: FIFO Property: random
Push(item) Enqueue(item) access
Pop()=item Dequeue()=item Kth(int) = item
IsEmpty()=true/false IsEmpty()=true/false SetKth(item,integer)
Implementation Hierarchy
List
Complexity: Unspecified
First()=pos Value(pos)=item Kth(integer)=item
Next(pos)=pos Length()=integer SetKth(item,integer)
Insert(item,pos) Delete(pos) Find(item)=position

Linked List Array


(1) for: (1) for:

(n) for: (n) for:


Specialization and Implementation
Hierarchies
List

Stack Queue Vector

Sorted Vector

Linked List
Concrete Data Types
List

b c 
Linked List

What’s an alternative
Linked List using implementation?
References
nodeB.value = “b”;
nodeC.value = “c”;
list = nodeB;
nodeB.next = nodeC
Concrete Data Types
List

b c 
Linked List

Linked List using Linked List using


References Arrays list = 4;
nodeB.value = “b”; “c” “b”
nodeC.value = “c”;
list = nodeB; 0 2
nodeB.next = nodeC
1 2 3 4 5
Linked Lists in C

L a b c 

struct node{
Object element;
struct node * next; }
Everything else is a pointer to a node!
typedef stuct node * List;
typedef struct node * Position;
Linked Lists in Java – version 1
• References to objects are implicit pointers

class ListNode{
Object element;
ListNode next; }
class List{
Listnode head;
Listnode find(Object item) {
Listnode n = head;
while (n != null) {
if (n.element == item)
return n; }
return null; }
Data Hiding
• Good programming style hides internal details of an object
from the rest of the program
– Guarantees that data structure always works as expected – cannot
easily be corrupted
• Here, must make details of ListNode and List public
– Type returned by find
– For iterating through a list:

ListNode n;
for (n = mylist.head; n!= null; n = n.next){
v = n.element;
do something on each v
}
Iterators
• Introduce a new public class to explicitly represent a position in a list

public class LinkedListItr {


ListNode current;
public Object retrieve() {
return current.element; }
public void advance() {
current = current.next; }
• Then:

LinkedListItr i;
for (i = mylist.first(); !i.pastEnd(); i.advance){
do something on each v.retrieve()
}
Abstract Iterators
• Iterators can also be defined for an array
implementation of lists:

public class ArrayListItr {


Object [] data;
integer current;
public Object retrieve() {
return data[current]; }
public void advance() {
current = current+1; }
• We can create an abstract iterator that works for both
linked list and array implements of List
Abstract Iterator
abstract class ListItr {
abstract Object retrieve();
abstract void advance();
… }

class LinkedListItr extends ListItr { … }


class ArrayListItr extends ListItr { … }

• Why do this?
Array Implementation of Linked Lists
1 2 3 4 5 6 7 8 9 10

Data F O A R N R T

Next 3 8 6 4 -1 10 5

First = 2

How do we implement
Delete(position) ?
Insert(element, position)?
Free Cell Management
1 2 3 4 5 6 7 8 9 10

Data F O A R N R T

Next 7 3 8 6 4 -1 9 10 0 5

First = 2 Free = 1

When an item is removed from the list, must


“reclaim” the unused cell for later use
Can use same array to manage a second list of
unused cells
Memory Management
• Keeping a free cell list is an example of a memory
management strategy
• How is memory managed in C?

• C++?

• Java?
Summary: Complexity
Linked list Array Sorted
array
Kth(int)

Find(e)

Insert(e,pos)

Next(pos)

InsertAnywhere(e)
To ADT or NOT to ADT?
• Issue: when to bypass / expand List
ADT?
• Using general list (stack) operations:
List reverse(List x) {
y = new List;
while (! x.isEmpty())
y.Push( x.Pop() )
return y; }
Disadvantages?
Destructive Method
x a b c 

a  b c x

Reverse() {
ListNode x, last, tmp;
x = head;
Faster in practice?
last = null;
while (x.next != null){
tmp = x.next; Asymptotically faster?
x.next = last;
last = x;
x = tmp;}
head = x; }
Slow Reverse
List reverse(List x) {
y = new List;
for (i=1; i<=x.length(); i++){
y.Push( x.Kth(i) )
}
return y; }
List ADT

Polynomial ADT
Possible linked list implementation:
Ai is the coefficient of the xi-1 term:

5 + 2x + 3x2 ( 5 2 3 )
7 + 8x ( 7 8 )
3 + x2 ( 3 0 2 )

Problem?
4 + 3x2001
( 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 )
Sparse Vector Data Structure:
4 + 3x 2001

(<4 0> <2001 3>)

4 3
0 2001

class Term { int coeff, power; }


class PolyNode extends ListNode {
Term data; }
class Polynomial extends List {
Polynode header;
… }
Addition of Two Polynomials?
Complexity?
15+10x50+3x1200

p 15 10 3
0 50 1200

5+30x50+4x100
q 5 30 4
0 50 100
Addition of Two Polynomials
• One pass down each list: (n+m)
15+10x50+3x1200

p 15 10 3
0 50 1200

5+30x50+4x100
q 5 30 4
0 50 100
r
20 40 4 3
0 50 100 1200
Sparse Matrices
18 0 33 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 99 0 0
0 0 0 0 0 0
0 0 0 0 0 27

• How could we represent this compactly?


Sparse Matrices
18 0 33 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 99 0 0
0 0 0 0 0 0
0 0 0 0 0 27

• How could we represent this compactly?


( (row (column data) (column data) …)
(row ( (column data) (column data) …)
…)
( (1 (1 18) (2 33)
(4 (4 99))
(5 (5 27)) )
Nested Polymorphic Lists
• Polymorphic – elements in list may be of different
types
– Trivial in Java, doable but painful in C++
• Nested – elements of a list is are lists
• Nested polymorphic list – elements of list may be
of non-list types (e.g. int) or lists
“Universal” Data Structure
• NPL’s can be used to implement any of the other
linked data structures we’ll cover in the course
– Trees, heaps, graphs, disjoint sets
• LISP – programming language that uses NPL’s to
represent both data and programs
– LISP pioneered (in the 1950’s!) many ideas that are the
basis of modern programming languages
• Recursion, garbage collection, interactive programming
environments
• JAVA combines the best features of LISP with the best features of
C++ (strict type checking, objects and inheritance)
Programs As Lists
(progn
(setq x 10)
(setq y 1)
(while (greater-than x 1)
(progn
(setq y (times y x))
(setq x (minus x 1)))))
-Lisp
• Let’s see how easy it is to build our own
programming language interpreter…
(plus (times (minus 6 2) 14) 8)

repeat 0 or
• Grammar for an expression: more times
expression :: = integer
| “(“ symbol {expression}* “)”

symbol ::= [a-z]+


repeat 1 or
more times
Lists
• For these slides: convention that head field of list
points directly to first node of list (no dummy node)
class Node {
Object element;
Node next; }

class List {
Node head;
… }
Read/Eval/Print Loop
• The top level program:

While (not EOF)


Print( Eval( ReadExpression()))
Reading Expressions
ReadExpression() { see Weiss
for
t = GetToken();
tokenizer
if (t is numeric)
return new Integer(t);
if (t is “(“))
return ReadList();
if (t is “)”) return null;
else return new Symbol(t);
}
ReadList
ReadList() {
e = ReadExpression();
if (e == null)
return a new empty List;
else return
Push( e, ReadList() );
}
Why is the recursive call inside the Push?
Evaluating Expressions
Eval( e ){
if (e is an Integer)
return its value;
if (e is a List)
f = e.head.element;
return Apply(f,
EvalList(e.head.next));
else error;
}
EvalList
EvalList(Node n){
if (n == null)
return a new empty list;
else return
Push( Eval(n.element),
EvalList(n.next) );
}
Apply
Apply(f, params){
if (f is “plus”)
return sum of params
else if (f is “minus”)
return difference of params
else …
} params is always a list
of ints – it has been
fully evaluated!
That’s It!
• 33 lines of pseudo-code
• About 100 lines of Java

• What about variables? If statements? Loops?


Adding Variables
• Keep an symbol table list of variable/value pairs
( (a 15) (b 22) (c –2) )
• Add to Eval:
– to evaluate a variable, find it in the symbol table and
return it’s value – if it is not the table, error.
– to set a variable, check for the special form
(set symbol expression)
Eval with Variables
Eval( e ){
if (e is an Integer)
return its value;
if (e is a List)
f = e.head.element;
if (f is “set”){
var = e.head.next.element;
val = e.head.next.next.element;
Put (var,val) in symbol table; }
else return Apply(f,
EvalList(e.head.next))
else return e’s value in symbol table;
}
Control Flow
• Sequence
(prog exp1 exp2 …)
– In Apply, return value of last parameter
• Conditionals
(if exp1 exp2 exp3)
– In Eval, if exp1 is not 0, evaluate exp2, otherwise exp3
• Loops
(loop exp1 exp2)
– In Eval, if exp1 is not 0, evaluate exp2, then repeat
Coming Up
• Sorting
– Weiss Chapter 7
• Know how the following work:
– Bubble Sort (selection sort)
– Merge Sort
– Quicksort

You might also like