1 lists. 2 overview arrays –random access: –fixed size: cannot grow on demand after creation: ...

34
1 Lists

Post on 15-Jan-2016

213 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 1 Lists. 2 Overview Arrays –Random access: –Fixed size: cannot grow on demand after creation:  Characteristics of some applications: –do not need random

1

Lists

Page 2: 1 Lists. 2 Overview Arrays –Random access: –Fixed size: cannot grow on demand after creation:  Characteristics of some applications: –do not need random

2

Overview• Arrays

– Random access: – Fixed size: cannot grow on demand after creation:

• Characteristics of some applications: – do not need random access– require a data structure that can grow and shrink

dynamically to accommodate different amounts of data

(Linked) Lists satisfy this requirement.• We study

– list creation– accessing elements in a list– inserting elements into a list– deleting elements from a list

Page 3: 1 Lists. 2 Overview Arrays –Random access: –Fixed size: cannot grow on demand after creation:  Characteristics of some applications: –do not need random

3

List: a sequence of cells in which each cell contains– a data item of type Object– a reference to the next cell

in the sequence (null if this is last cell in the sequence)

– empty list: null• List is a sequential-access

data structure– to access data in position n

of sequence, we must access cells 0..n-1

• We will define a class ListCell from which we will build lists.

24 -7 87 78

Array:

lc

0 1 2 3

02

our symbol for null

a0aa0

Lista1

24 a6

a1

-7 a8

a6

87 a2

a8

78

a21

3

Page 4: 1 Lists. 2 Overview Arrays –Random access: –Fixed size: cannot grow on demand after creation:  Characteristics of some applications: –do not need random

4

Class ListCell/** An instance is a cell of a list, with a value and a name of another cell */public class ListCell { protected Object datum; // value of cell protected ListCell next; // name of next cell //(null if none)

/** Constructor: cell with value ob and next cell n */ public ListCell(Object ob, ListCell n){ …

/** = the value in this cell */ public Object getDatum() {//sometimes called car} /** = name of next cell (none if none)*/ public ListCell getNext() {// … called cdr}

/** Set value to ob */ public void setDatum(Object ob) {// … called rplaca }

/** Set next cell to n public void setNext(ListCell n) {//… called rplacd}} This is how we draw ListCells

24 a6

a1

a1

ListCelldatum 24

next a6

ListCell(Object, ListCell)

getDatum() getNext()

setDatum(Object)

setNext(ListCell)

Page 5: 1 Lists. 2 Overview Arrays –Random access: –Fixed size: cannot grow on demand after creation:  Characteristics of some applications: –do not need random

5

Class ListCell

/** Instance: a cell of list, with a value and a name of a cell */public class ListCell { private Object datum; // value of cell private ListCell next; // name of next cell (null if none)

/** Constructor: cell with value ob and next cell n */ public ListCell(Object ob, ListCell n) { datum= ob; next= n; }

/** = the value in this cell */ public Object getDatum() { return datum; }

/** = name of next cell (none if none)*/ public ListCell getNext() { return next; }

/** Set value to ob */ public void setDatum(Object ob) { datum= ob; }

/** Set next cell to n public void setNext(ListCell n) { next= n; }}

Page 6: 1 Lists. 2 Overview Arrays –Random access: –Fixed size: cannot grow on demand after creation:  Characteristics of some applications: –do not need random

6

Building a listInteger t= new Integer(24);Integer s= new Integer(-7);Integer e= new Integer(87);

ListCell p= new ListCell(e,null);

p= new ListCell(s,p);

p= new ListCell(t,p);

// Store in p a list 24, -7, 87

Note: assignment of form p = new ListCell(s,p); does notcreate a circular list.

p a587

a5

87

a5

p a6 87 a5

a6

87

a5

p a6 87 a5

a6

24 a6

a7

Page 7: 1 Lists. 2 Overview Arrays –Random access: –Fixed size: cannot grow on demand after creation:  Characteristics of some applications: –do not need random

7

Building a list

Integer t = new Integer(24);Integer s = new Integer(-7);Integer e = new Integer(87);

// Store in p a list of 24, -7, 87

ListCell p = new ListCell(t, new ListCell(s, new ListCell(e,null)));

Another way:

87

a5

-7 a5

a6

24 a6

a7p a7

Page 8: 1 Lists. 2 Overview Arrays –Random access: –Fixed size: cannot grow on demand after creation:  Characteristics of some applications: –do not need random

8

Accessing list elements

• Lists are sequential-access data structures.– to access the contents of cell n in sequence,

you must access cells 0..n-1 • Accessing data in first cell: p.getDatum() • Accessing data in second cell:

p.getNext().getDatum()• Accessing next field in second cell:

p.getNext().getNext()

87

a5

-7 a5

a6

24 a6

a7p a7

p.getDatum() p.getNext()

Page 9: 1 Lists. 2 Overview Arrays –Random access: –Fixed size: cannot grow on demand after creation:  Characteristics of some applications: –do not need random

9

Accessing list elements

Writing to fields in cells can be done the same way

//update data field of first cell

p.setDatum(new Integer(53)); ));

//update field of second cell p.getNext().setDatum(new Integer(53));

//chop off third cell

p.getNext().setNext(null);

87

a5

-7 a5

a6

24 a6

a7p a7

Page 10: 1 Lists. 2 Overview Arrays –Random access: –Fixed size: cannot grow on demand after creation:  Characteristics of some applications: –do not need random

10

Access example: linear search

// = “ob is in list p”

public static boolean search(Object ob, ListCell p) {

// invariant: c is the name of a cell in list p (or null)

// ob does not occur before cell c in list p

for (ListCell c= p; ci != null; c= c.getNext())

if (c.getDatum().equals(ob)) return true;

// { ob is not in the list }

return false;

}

87

a5

-7 a5

a6

24 a6

a7p a7

Page 11: 1 Lists. 2 Overview Arrays –Random access: –Fixed size: cannot grow on demand after creation:  Characteristics of some applications: –do not need random

11

Recursion on lists

• Recursion can be done on lists in a manner similar to recursion on integers.

• Almost always– base case: empty list– recursive case: assuming you can solve problem on

(smaller) list obtained by eliminating first cell, write down solution for list

• Many list problems can be solved very simply by using this idea.– Some problems, though, are easier to solve

iteratively.

Page 12: 1 Lists. 2 Overview Arrays –Random access: –Fixed size: cannot grow on demand after creation:  Characteristics of some applications: –do not need random

12

Recursion example: linear search

• Base case: empty list– return false

• Recursive case: non-empty list– if data in first cell equals object ob, return true– else return result of doing linear search on rest of list

// = “ob occurs in list p” */public static boolean recSearch(Object ob, ListCell p) { if (p == null) return false; return p.getDatum().equals(ob) || recSearch(ob,p.getNext());}

Page 13: 1 Lists. 2 Overview Arrays –Random access: –Fixed size: cannot grow on demand after creation:  Characteristics of some applications: –do not need random

13

Some prefer to use a class List that is distinct from class ListCell.A List object is like a head element that always exists even if list

itself is empty./** An instance is a list with a header */ class List { private ListCell head; /** Constructor: an instance is a list p public List (ListCell p) {head= p; }

/** = the first value of list (0 if none) public ListCell getHead() { … }

/** Set list to p */ public void setHead(ListCell p) { … }

87

a5

-7 a5

a6

24 a6

a7

List with header

p a1head

a1

a7

Page 14: 1 Lists. 2 Overview Arrays –Random access: –Fixed size: cannot grow on demand after creation:  Characteristics of some applications: –do not need random

14

Variations of list with header

• Header can keep other info, e.g.– reference to last cell of list– number of elements in list– search/insertion/ deletion

as instance methods

87

a5

-7 a5

a6

24 a6

a7p1 a1

a1

head

a7

p2 b2b2

tail a5

head

a7

p3 c3c3

size

3

head

a7

search(ob)

What you put in a header depends

on the application.

Page 15: 1 Lists. 2 Overview Arrays –Random access: –Fixed size: cannot grow on demand after creation:  Characteristics of some applications: –do not need random

15

Example of use of class List

• We write code to – insert object into unsorted list– delete the first occurrence of an object in an unsorted list.

• We use the class List to show how to use this class.– It is just as easy to write code without the header element.

• Methods for insertion/deletion will be instance methods in class List.// insert ob into front of this listpublic void insertHead(Object ob);

// insert ob into front of this listpublic void insertTail(Object ob);

// delete ob from this list (if it is there)public void delete(Object ob);

Page 16: 1 Lists. 2 Overview Arrays –Random access: –Fixed size: cannot grow on demand after creation:  Characteristics of some applications: –do not need random

16

Insertion into tail of list

public class List{private ListCell head;public void insertHead(Object ob) { head= new ListCell(ob,head) }… }

8787

a5

-7 a5

a6

24 a6

a7p a1

head

a1

a8

p.insertHead(new Integer(6));

6 a7

a8

Page 17: 1 Lists. 2 Overview Arrays –Random access: –Fixed size: cannot grow on demand after creation:  Characteristics of some applications: –do not need random

17

Insertion into Tail of list

public class List{private ListCell head;public void insertTail(Object ob) { if (head == null) head = new ListCell(ob, null) else { // Store in c the name of the tail of the list ListCell= head; while (c.getNext() != null) c= c.getNext();

c.setNext(new ListCell(ob, null)); }

}

87

87 a9

a5

-7 a5

a6

24 a6

a7p a1

head

a1

a7

p.insertTail(new Integer(6));

6

a9

Page 18: 1 Lists. 2 Overview Arrays –Random access: –Fixed size: cannot grow on demand after creation:  Characteristics of some applications: –do not need random

18

Example of use of insert methods

List p= new List(null); //List p is empty

p.insertHead(new Integer(-7)); //p contains -7

p.insertHead(new Integer(24)); //p contains 24, -7

p.insertTail(new Integer(87)); //p contains 24, -7, 87……

87-7 a5

a6

24 a6

a7p a1

head

a1

a7 87

a5

Page 19: 1 Lists. 2 Overview Arrays –Random access: –Fixed size: cannot grow on demand after creation:  Characteristics of some applications: –do not need random

19

Remove first item from list

/** remove and return the first element of this list. Throw RuntimeException if this list is empty. */public Object deleteFirst(){ if (head == null) { throw new RuntimeException(“List is empty”); }

Object t= head.getDatum();head= head.getNext();return t;

}

-7 a5

a6

24 a6

a7p a7

head

a1

a7 87

a5

Page 20: 1 Lists. 2 Overview Arrays –Random access: –Fixed size: cannot grow on demand after creation:  Characteristics of some applications: –do not need random

20

Remove and return last item from list

Cases:• list is empty:

throw an exception

• list contains one element: change head

• list contains >2 elements: change next-to-last element

-7 a5

a6

24 a6

a7p a1

head

a1

a7 87

a5

p a1head

a1

null

p a1head

a1

a7

24

a7

Page 21: 1 Lists. 2 Overview Arrays –Random access: –Fixed size: cannot grow on demand after creation:  Characteristics of some applications: –do not need random

21

Finding penultimate element of list

/** List size >= 2. Return nameof penultimate element */

private Object getPenultimate() {ListCell c= head; ListCell scout= head.getNext();/** invariant: c is name of a cell of the list,

c.getNext() is not null,scout is the next cell following c */

while (scout.getNext() != null){c= scout;scout= scout.getNext();

}return c;

}

-7 a5

a6

24 a6

a7p a1

head

a1

a7 87

a5

“penultimate” means

“next to last”

Page 22: 1 Lists. 2 Overview Arrays –Random access: –Fixed size: cannot grow on demand after creation:  Characteristics of some applications: –do not need random

22

Remove and return last item from list

/** remove and return last element of list. Throw RuntimeException if list is empty */public Object deleteLast(){

if (head == null) throw new RuntimeException(“list is empty”);

if (head.getNext() == null) {Object t= head.getDatum();head= null;return t;

}// { list contains at least two elements }ListCell penultimate= getPenultimate;ListCell last= penultimate.getNext();penultimate.setNext(null);return last.getDatum();

} -7 a5

a6

24 a6

a7

p a1head

a1

a7

87

a5

Page 23: 1 Lists. 2 Overview Arrays –Random access: –Fixed size: cannot grow on demand after creation:  Characteristics of some applications: –do not need random

23

Delete object from list

• Delete first occurrence of an object ob from a list p.

• Idea of recursive code:

– If list p is empty, return null.

– If first element of p is ob, return rest of list p.

– Otherwise, return list consisting of first element of p, and the list that results from deleting p from the rest of list p.

-7 a5

a6

24 a6

a7p a1

head

a1

a7 87

a5

Page 24: 1 Lists. 2 Overview Arrays –Random access: –Fixed size: cannot grow on demand after creation:  Characteristics of some applications: –do not need random

24

Recursive code for deletepublic class List{ private ListCell head; // Delete first occur. of ob from list (if it is there) public void delete(Object ob) { head= deleteRec(ob, head); } // = list lc but with first occur. of ob deleted (if there) private static ListCell deleteRec(Object ob, ListCell lc) { if (lc == null) return null; // handle empty list // { list lc is not empty } if (l.getDatum().equals(ob)) return lc.getNext(); // { first element of lc is not ob } lc.setNext(deleteRec(ob, lc.getNext())); return l; }}

Page 25: 1 Lists. 2 Overview Arrays –Random access: –Fixed size: cannot grow on demand after creation:  Characteristics of some applications: –do not need random

25

Finding elemelement of list

/** First element of list c is not ob. Return name of element that precedes ob (or null if none) */private Object getOb(ListCell c, Object ob) {

ListCell scout= head.getNext();/** invariant: c is name of a cell of the list,

c.getDatum() is not ob.scout is name of next element (null if none) */

while (scout != null && !scout.getDatum().equals(ob)){c= scout;scout= scout.getNext();

}if (scout == null) return null;return c;

}

-7 a5

a6

24 a6

a7p a1

head

a1

a7 87

a5

Page 26: 1 Lists. 2 Overview Arrays –Random access: –Fixed size: cannot grow on demand after creation:  Characteristics of some applications: –do not need random

26

Iterative code for delete

// Delete ob from list, if therepublic void delete(Object ob) { if (head == null) return; // If first element is ob, remove it and return if (head.getDatum().equals(o)) { head= head.getNext(); return; } // { First element of list is not ob } ListCell preceding= getOb(head, ob); if (preceding == null) return; //splice out cell containing ob preceding.setNext(preceding.getNext());}

Page 27: 1 Lists. 2 Overview Arrays –Random access: –Fixed size: cannot grow on demand after creation:  Characteristics of some applications: –do not need random

27

Insertion and deletion with sorted lists

• Assume that we have a list of Comparables sorted in increasing order.

• We want to splice a new Comparable into this list, keeping new list in sorted order as shown in figure.

• Code shows recursive code for insertion and deletion.

• We show code that uses class ListCell directly.

24 a5

a6

-7 a6

a7p a1

head

a1

a7 87

a5

Page 28: 1 Lists. 2 Overview Arrays –Random access: –Fixed size: cannot grow on demand after creation:  Characteristics of some applications: –do not need random

28

Recursive insertion

Use notation [f,n] to denote ListCell whose•datum is f•next is n

Pseudo-code: insert (Comparable c, ListCell l): if l is null return new ListCell(c,null); else suppose l is [f,n] if (c < f) return new ListCell(c,l); else return new ListCell(f, insert(c,n));Compactly: insert(c,null) = [c,null] insert(c,[f,n]) = [c,[f,n]] if c < f [f, insert(c,n)] if c >= f

Page 29: 1 Lists. 2 Overview Arrays –Random access: –Fixed size: cannot grow on demand after creation:  Characteristics of some applications: –do not need random

29

/** lc is a sorted list. Insert c into it */public static ListCell insert(Comparable c, ListCell lc) {

if (lc == null) return new ListCell(c, lc);

// { list has at least one element }if (c.compareTo(lc.getDatum()) < 0)

return new ListCell(c, lc);// { first element of list is > c }lc.setNext(insert(c,lc.getNext()));return lc;}

}

Page 30: 1 Lists. 2 Overview Arrays –Random access: –Fixed size: cannot grow on demand after creation:  Characteristics of some applications: –do not need random

30

/** List lc is sorted. Delete first occ. of c from it (if there) */public static ListCell delete(Comparable c, ListCell lc) {

if ((l == null)return null;

if (c.compareTo(lc.getDatum()) < 0) return lc; if (c.compareTo(lc.getDatum()) == 0)

return lc.getNext();lc.setNext(delete(c,lc.getNext()));return lc;

}

Page 31: 1 Lists. 2 Overview Arrays –Random access: –Fixed size: cannot grow on demand after creation:  Characteristics of some applications: –do not need random

31

Exercises

1. Write insert into a sorted list without recursion.

2. Write delete from a sorted list without recursion.

Page 32: 1 Lists. 2 Overview Arrays –Random access: –Fixed size: cannot grow on demand after creation:  Characteristics of some applications: –do not need random

32

Doubly-linked lists

• In some applications, it is convenient to have a ListCell that references both its predecessor and its successor in the list.public class DLLCell { private Object datum; private DLLCell next; private DLLCell previous; …..}

-7 a6

a7p a7

a7 24 a5

a6

a6 8

a5

Page 33: 1 Lists. 2 Overview Arrays –Random access: –Fixed size: cannot grow on demand after creation:  Characteristics of some applications: –do not need random

33

• In general, it is easier to work with doubly-linked lists than with lists.

• For example, reversing a DLL can be done simply by swapping the previous and next fields of each cell.

• Trade-off: DLLs require more space than singly-linked lists.

Page 34: 1 Lists. 2 Overview Arrays –Random access: –Fixed size: cannot grow on demand after creation:  Characteristics of some applications: –do not need random

34

Summary

• Lists are sequences of ListCell elements– recursive data structure– grow and shrink on demand– not random-access but sequential access data structures

• List operations:– create a list– access a list and update data– change structure of list by inserting/deleting cells

• cursors• Recursion makes perfect sense on lists. Usually

– base case: empty list, perhaps one-element list also– recursive case: non-empty list

• Sub-species of lists– list with header– doubly-linked lists