These notes are intended for use by students in CS0445 at the University of Pittsburgh and no one else - PowerPoint PPT Presentation

About This Presentation
Title:

These notes are intended for use by students in CS0445 at the University of Pittsburgh and no one else

Description:

– PowerPoint PPT presentation

Number of Views:349
Avg rating:3.0/5.0
Slides: 362
Provided by: peopleCs7
Category:

less

Transcript and Presenter's Notes

Title: These notes are intended for use by students in CS0445 at the University of Pittsburgh and no one else


1
(No Transcript)
2
  • These notes are intended for use by students in
    CS0445 at the University of Pittsburgh and no one
    else
  • These notes are provided free of charge and may
    not be sold in any shape or form
  • Material from these notes is obtained from
    various sources, including, but not limited to,
    the following
  • Data Structures and Abstractions with Java, 2nd
    and 3rd Editions by Frank Carrano
  • Data Structures and the Java Collections
    Framework by William Collins
  • Classic Data Structures in Java by Timothy Budd
  • Java By Dissection by Pohl and McDowell
  • Java Software Solutions (various editions) by
    John Lewis and William Loftus
  • java.sun.com and its many sub-links

3
Goals of Course
  • To learn, understand and be able to utilize many
    of the data structures that are fundamental to
    computer science
  • Data structures such as vectors, stacks, queues,
    linked-lists and trees are used throughout
    computer science
  • We should understand these from a user's point of
    view
  • What are these data structures and how do I use
    them in my programs?

4
Goals of Course
  • To understand implementation issues related to
    these data structures, and to see how they can be
    implemented in the Java programming language
  • Data structures can be implemented in various
    ways, each of which has implications (ex
    run-time differences, code complexity,
    modifiability)
  • We should understand these data structures from
    an implementer's point of view
  • How can these data structures be effectively
    implemented?

5
Goals of Course
  • To understand and utilize programming ideas and
    techniques utilized in data structure
    implementation
  • Object-oriented programming, dynamic memory
    utilization, recursion and other principles must
    be understood in order to effectively implement
    data structures
  • What tools must I know and be able to use in
    order to implement data structures?

6
Goals of Course
  • To learn more of the Java programming language
    and its features, and to become more proficient
    at programming with it
  • Java is a very large language with extensive
    capabilities
  • As your programming skills improve, you can
    utilize more of these capabilities effectively
  • Since I am working with Java, how well can I
    learn and use the language and its features?

7
Lecture 1 Getting Started
  • How and where can I use Java?
  • Java is a platform-independent language, and thus
    can be used on many different platforms
  • In CS 0401 last term, you used Mac Minis
  • Some of you may have PCs or prefer PCs in the
    labs
  • Programs written in either place should run the
    same way

Win32 PC
Java Program
Sun Workstation
8
Lecture 1 Review
  • Last term in CS 0401 you learned many things that
    you will need to use this term
  • Basic Java program structure and syntax
  • Java control structures and utilizing them
    effectively
  • Loops, conditionals, etc
  • Java methods and method calls
  • With and without parameters
  • Static methods vs instance methods
  • Java variables and objects
  • Instance variables vs method variables
  • Objects vs references
  • Dynamic nature of Java objects

9
Lecture 1 Review
  • Java classes
  • Syntax for writing new classes
  • Inheritance
  • Polymorphism via method overriding and
    overloading
  • Interfaces, how and why to use them
  • Simple Java files and graphics
  • Exception handling
  • If you are unsure about these things, look them
    over in your notes and in your CS 0401 textbook
  • Also read Appendices A-F in the Carrano Data
    Structures text
  • We will briefly go over Appendices B, C and D and
    review some of these concepts in the first few
    lectures

10
Lecture 1 Classes and Objects
  • Classes are blueprints for our data
  • The class structure provides a good way to
    encapsulate the data and operations of a new type
    together
  • Instance data and instance methods
  • Access restrictions (i.e. data hiding through
    private declarations) allow the implementation
    details of the data type to be hidden from a user
  • public, protected and private allow various
    levels of accessibility

11
Lecture 1 Classes and Objects
  • User of the class knows the nature of the data,
    and the public methods, but NOT the
    implementation details
  • But does not need to know them in order to use
    the class
  • Ex BigInteger
  • These are determined by the specifics of the
    private data and the method implementations
  • We call this data abstraction
  • This is related to abstract data types (ADTs),
    which we will discuss shortly

12
Lecture 1 Classes and Objects
  • Java classes determine the structure of Java
    objects
  • public declarations (typically methods) give the
    interface and functionality of the objects
  • How the outside world communicates with the
    objects
  • private declarations (typically data and some
    methods) hide the implementation details from the
    user
  • To put it another way, Java objects are instances
    of Java classes

13
Lecture 1 Classes and Objects
  • Class declaration keywords
  • public accessible outside class
  • private inaccessible outside class
  • protected accessible only within class and
    subclasses and same package
  • static part of class rather than instance
    shared by all instances
  • final constant cannot be assigned
    (variables), overridden (methods) or subclassed
    (classes)

14
Lecture 1 References, Pointers and Memory
  • Other than the primitive variables, all Java
    variables are references

15
Lecture 1 References, Pointers and Memory
  • Be careful when comparing
  • Know when you want to compare references or
    contents
  • For reference variables, we typically need to use
    a method to compare contents
  • ex. for strings, equals
  • u.equals(s) returns true
  • We can redefine equals() for our own classes as
    well
  • Java does not allow operator overloading, so we
    cannot redefine comparison operators to compare
    contents must use named methods

16
Lecture 2 References, Pointers and Memory
  • How do references and pointers relate?
  • Many programming languages (ex C, C, Pascal)
    use pointer variables
  • Pointers are variables that store addresses of
    other memory locations
  • Pointers allow indirect access of the data in
    objects

Object A
101001
X
010010
010010
Object B
Y
101001
17
Lecture 2 References, Pointers and Memory
  • So the value stored in a pointer is an address
  • However, if you dereference a pointer, you gain
    access to the object it "points to"

X Y // Changes what X points to // X
no longer has access to // Object B
Object A
101001
X
101001
010010
Object B
Y
101001
18
Lecture 2 References, Pointers and Memory
  • In C, you dereference pointers using the
    operator

X Y// Changes contents of object //
that X points to. The // value of X is
unchanged
Object A
101001
X
010010
010010
Object A
Y
101001
19
Lecture 2 References, Pointers and Memory
  • References in Java
  • Behave in a way similar to pointers, but with
    more restriction
  • Dereferencing is implicit there is no
    dereference operator
  • Reference values (addresses) can be assigned but
    they cannot be manipulated
  • But aliasing still occurs and you must be very
    careful
  • Be aware of when you want a new object or a
    reference to an old one

20
Lecture 2 References, Pointers and Memory
  • Java Memory Use
  • All objects in Java are allocated dynamically
  • Memory is allocated using the new operator
  • Once allocated, objects exist for an indefinite
    period of time
  • As long as there is an active reference to the
    object
  • Objects that have no references to them are no
    longer accessible in the program
  • Ex. Object B in slide 17
  • These objects are marked for GARBAGE COLLECTION

21
Lecture 2 References, Pointers and Memory
  • The Java garbage collector is a process that runs
    in the background during program execution
  • When the amount of available memory runs low, the
    garbage collector reclaims objects that have been
    marked for collection
  • A fairly sophisticated algorithm is used to
    determine which objects can be garbage collected
  • If you take CS 1621 or CS 1622 you will likely
    discuss this algorithm in more detail
  • If plenty of memory is available, there is a good
    chance that the garbage collector will never run
  • See Example1.java

22
Lecture 2 Building New Classes
  • Java has many predefined classes
  • Class library contains hundreds of classes, each
    designed for a specific purpose
  • See API http//download.oracle.com/javase/6/docs
    /api/
  • However, in many situations we may need a class
    that is not already defined
  • We will have to define it ourselves
  • There are two primary techniques for doing this
  • Composition (Aggregation)
  • Inheritance

23
Lecture 2 Composition
  • With composition, we build a new class using
    components (instance variables) that are from
    previously defined classes
  • We compose the class from existent "pieces"
  • "Has a" relationship between new class and old
    classes
  • New class has no special access to its instance
    variable objects
  • Methods in new class are often implemented by
    utilizing methods from the instance variable
    objects

24
Lecture 2 Composition
  • public class CompoClass
  • private String name
  • private Integer size
  • public CompoClass(String n, int i)
  • name new String(n)
  • size new Integer(i)
  • public setCharAt(int i, char c)
  • StringBuilder b new StringBuilder(name)
  • b.setCharAt(i, c)
  • name b.toString()
  • We cannot access the inner representation of the
    String, and String objects are immutable, so we
    must change it in the rather convoluted way shown
    above

25
Lecture 2 Inheritance
  • With inheritance, we build a new class (subclass)
    by extending a previously defined class
    (superclass)
  • Subclass has all of the properties (data and
    methods) defined in the superclass
  • "Is a" relationship between subclass and
    superclass
  • Subclass is a superclass, and subclass objects
    can be assigned to superclass variables
  • Not vice versa!
  • Superclass IS NOT a subclass and superclass
    objects cannot be assigned to subclass variables

26
Lecture 2 Inheritance
  • // Assume SubFoo is a subclass of Foo see notes
  • // below and on board
  • Foo f1
  • SubFoo s1
  • f1 new Foo() // fine
  • f1 new SubFoo() // also fine however, now
    we
  • // only have access to the public methods
    and
  • // variables defined in class Foo()
  • f1.foomethod() // fine
  • f1.subfoomethod() // illegal
  • ((SubFoo)f1).subfoomethod() // fine, since now
    the ref.
  • // has been cast to the actual class
  • s1 new SubFoo() // also fine now all SubFoo
  • // public methods and variables are
    accessible
  • s1.subfoomethod() fine
  • s1.foomethod() // also fine
  • s1 new Foo() // illegal

27
Lecture 2 Polymorphism
  • Allows superclass and subclass objects to be
    accessed in a regular, consistent way
  • Array or collection of superclass references can
    be used to access a mixture of superclass and
    subclass objects
  • If a method is defined in both the superclass and
    subclass (with identical signatures), the version
    corresponding to each class will be used in a
    call from the array
  • Idea is that the methods are similar in nature
    but the redefinition in the subclass gears the
    method more specifically to the data / properties
    of the subclass

28
Lecture 2 Polymorphism
  • Ex. Each subclass overrides the move() method in
    its own way
  • Animal A new Animal3
  • A0 new Bird()
  • A1 new Person()
  • A2 new Fish()
  • for (int i 0 i lt A.length i)
  • Ai.move()

Animal
move()
move()
  • References are all the same, but objects are not
  • Method invoked is that associated with the
    OBJECT, NOT with the reference

move()
29
Lecture 2 Polymorphism
  • Polymorphism is implemented utilizing two
    important ideas
  • Method overriding
  • A method defined in a superclass is redefined in
    a subclass with an identical method signature
  • Since the signatures are identical, rather than
    overloading the method (ad hoc polymorphism), it
    is instead overriding the method
  • For a subclass object, the definition in the
    subclass replaces the version in the superclass,
    even if a superclass reference is used to access
    the object
  • Superclass version can still be accessed via the
    super reference

30
Lecture 2 Polymorphism
  • Dynamic (or late) binding
  • The code executed for a method call is associated
    with the call during run-time
  • The actual method executed is determined by the
    type of the object, not the type of the reference
  • Polymorphism is very useful if we want to access
    collections of mixed data types consistently
  • Ex A collection of different graphical figures,
    each with a draw() method
  • Each is drawn differently, so it has a different
    draw() method, but the call is consistent

31
Lecture 2 Abstract Classes
  • Abstract classes
  • Sometimes in a class hierarchy, a class may be
    defined simply to give cohesion to its subclasses
  • No objects of that class will ever be defined
  • But instance data and methods will still be
    inherited by all subclasses
  • This is an abstract class
  • Keyword abstract used in declaration
  • One or more methods declared to be abstract and
    are thus not implemented
  • No objects may be instantiated

32
Lecture 2 Abstract Classes
  • Subclasses of an abstract class must implement
    all abstract methods, or they too must be
    declared to be abstract
  • Advantages
  • Can still use superclass reference to access all
    subclass objects in polymorphic way
  • However, we need to declare the methods we will
    need in the superclass, even if they are abstract
  • No need to specifically define common data and
    methods for each subclass - it is inherited
  • Helps to organize class hierarchy
  • See API for many examples

33
Lecture 3 Interfaces
  • Java allows only single inheritance
  • A new class can be a subclass of only one parent
    (super) class
  • There are several reasons for this, from both the
    implementation (i.e. how to do it in the compiler
    and interpreter) point of view and the programmer
    (i.e. how to use it effectively) point of view
  • However, it is sometimes useful to be able to
    access an object through more than one superclass
    reference

34
Lecture 3 Interfaces
  • Interfaces allow us to do this
  • A Java interface is a named set of methods
  • Think of it as an abstract class with no instance
    data
  • Static constants are allowed
  • No static methods are allowed
  • Any Java class (no matter what its inheritance)
    can implement an interface by implementing the
    methods defined in it
  • A given class can implement any number of
    interfaces

35
Lecture 3 Interfaces
  • Ex
  • public interface Laughable
  • public void laugh()
  • public interface Booable
  • public void boo()
  • Any Java class can implement Laughable by
    implementing the method laugh()
  • Any Java class can implement Booable by
    implementing the method boo()

36
Lecture 3 Interfaces
  • Ex
  • public class Comedian implements Laughable,
    Booable
  • // various methods here (constructor, etc.)
  • public void laugh()
  • System.out.println(Ha ha ha)
  • public void boo()
  • System.out.println(You stink!)

37
Lecture 3 Interfaces
  • Recall our previous discussion of polymorphism
  • This behavior also applies to interfaces the
    interface acts as a superclass and the
    implementing classes implement the actual methods
    however they want
  • An interface variable can be used to reference
    any object that implements that interface
  • However, only the interface methods are
    accessible through the interface reference
  • Ex
  • Laughable funny new Laughable3
  • funny0 new Comedian()
  • funny1 new SitCom() // implements Laughable
  • funny2 new Clown() // implements Laughable
  • for (int i 0 i lt funny.length i)
  • funnyi.laugh()
  • See ex16.java, Laughable.java and Booable.java
    from CS 0401 Handouts

38
Lecture 3 Generic Operations
  • Lets look at a simple example that should
    already be familiar to you Sorting
  • In CS 401 you should have discussed selection
    sort
  • Simple algorithm
  • Find smallest, swap into location 0
  • Find next smallest, swap into location 1, etc.
  • What if we want to sort different types (ints,
    doubles, Strings, or any Java type)?
  • We need to write a different method for each
    one!!!
  • The argument array must match the parameter array
  • Or do we??
  • Can we write a single method that can sort
    anything?
  • Use an interface! Discuss

39
Lecture 3 Generic Operations
  • Consider the (old) Comparable interface
  • It contains one method
  • int compareTo(Object r)
  • Returns a negative number if the current object
    is less than r, 0 if the current object equals r
    and a positive number if the current object is
    greater than r
  • Look at Comparable in the API
  • Consider what we need to know to sort data
  • is Ai less than, equal to or greater than Aj
  • Thus, we can sort Comparable data without knowing
    anything else about it
  • Awesome!
  • Polymorphism allows this to work

40
Lecture 3 Generic Operations
  • Think of the objects we want to sort as black
    boxes
  • We know we can compare them because they
    implement Comparable
  • We dont know (or need to know) anything else
    about them even though they may have many other
    methods / instance variables
  • Show on board
  • Thus, a single sort method will work for an array
    of any Comparable class
  • Did I mention that this was awesome!?

41
Lecture 3 "Generic" Operations
  • Note In JDK 1.5 Java improved its generic
    abilities by introducing parameterized types,
    interfaces and methods
  • We will discuss these in more detail at different
    points throughout the term
  • Right now, let's just look at the Comparable
    interface
  • Old Version
  • public interface Comparable
  • public int compareTo(Object rhs)
  • New Version
  • public interface ComparableltTgt
  • public int compareTo(T rhs)

42
Lecture 3 "Generic" Operations
  • Both versions allow arbitrary objects to be
    compared
  • The difference is that in the parameterized
    version, the types of the objects can be
    established and checked at compile-time
  • With the original version, this could not be done
    until run-time
  • To see this consider the parameter to the
    compareTo() method
  • In the orginal version it is Object
  • In the parameterized version it is T (i.e.
    whichever type is passed into the parameter)

43
Lecture 3 "Generic" Operations
  • Now, for 2 objects, C1 and C2, consider the call
  • C1.compareTo(C2)
  • In the orginal version, the compiler could not do
    any type checking, since C2 can be any Object
  • So if C2's object was incompatible with C1's
    object (i.e. apples and oranges) this problem
    would not be known until program execution
  • In the new version, the compiler can check the
    type of C2 and make sure it matches with the type
    set for T in the definition of compareTo
  • If the types are incompatible, the compiler will
    give an error

44
Lecture 3 "Generic" Operations
  • Why do we care?
  • Compilation errors are typically much easier to
    resolve than run-time errors
  • We'd like to "push" as much of the error-checking
    as possible to compile-time, while preserving the
    flexibility of the language
  • Parameterized types allow this to be done
  • Let's put all of this together in another handout
  • See Example2.java, People.java, Worker.java,
    Student.java, SortArray.java

45
Lecture 3 More on Java Generics
  • Java allows for generic interfaces, classes and
    methods
  • We saw interface example ComparableltTgt
  • Let's look at a simple class example and a simple
    method example
  • We will revisit this topic again probably more
    than once
  • Let's try to (very simply) mimic the
    functionality of a Java array
  • We want to be a create an object with an
    arbitrary number of locations
  • However, once created, the size is fixed

46
Lecture 3 More on Java Generics
  • We want the underlying type to be any Java type
  • However, it should be homogeneous cannot mix
    types (except if type is a superclass)
  • We want to be able to assign a value to a
    location
  • We want to be able to retrieve a value from a
    location
  • We want to be able to tell the size of the array
  • Let's see how to do this with Java Generics
  • See MyArray.java and Example3.java
  • Note that MyArray is not really a useful type
    it is just meant to demonstrate parameterized
    Java types

47
Lecture 4 Abstract Data Types
  • Abstract Data Types (ADTs)
  • We are familiar with data types in Java
  • For example some primitive data types int,
    float, double, boolean, or reference types such
    as String
  • We can think of these as a combination (or
    encapsulation) of two things
  • The data itself and its representation in memory
  • For classes these are the instance variables
  • The operations by which the data can be
    manipulated
  • For classes these are the methods

48
Lecture 4 Abstract Data Types
  • For example, the int type in Java
  • We can think of it simply as whole numbers,
    represented in some way in the computer, but this
    would be incomplete
  • What makes integers useful is the operations that
    we can do on them, for example , -, , /, and
    others
  • It is understanding the nature of the data
    together with the operations that can be done on
    it that make ints useful to us
  • We also discussed BigInteger previously

49
Lecture 4 Abstract Data Types
  • So where does the abstract part come in?
  • Note that in order to use ints in our programs,
    we ONLY need to know what they are and what their
    operations are
  • We do NOT need to know their implementation
    details
  • Does it matter to me how the int or BigInteger is
    represented in memory?
  • Does it matter how the actual division operation
    is done on the computer?
  • For the purposes of using integers effectively in
    most situationsNO!

50
Lecture 4 Abstract Data Types
  • More generally speaking, an ADT is a data type
    (data operations) whose functionality is
    separated from its implementation
  • The same functionality can result from different
    implementations
  • Users of the ADT need only to know the
    functionality
  • Naturally, however, to actually be used, ADTs
    must be implemented by someone at some point
  • Implementer must be concerned with the
    implementation details
  • In this course you will look at ADTs both from
    the user's and implementer's point of view

51
Lecture 4 ADTs vs. Classes
  • The previous slides should be familiar to you
  • We have already discussed the idea of data
    abstraction from classes
  • ADTs are language-independent representations of
    data types
  • Can be used to specify a new data type that can
    then be implemented in various ways using
    different programming languages
  • Classes are language-specific structures that
    allow implementation of ADTs
  • Only exist in object-oriented or object-based
    languages

52
Lecture 4 ADTs vs. Classes
  • A given ADT can be implemented in different ways
    using different classes
  • We will see some of these soon
  • Ex Stack, Queue, SortedList can be implemented
    in different ways
  • A given class can in fact be used to represent
    more than one ADT
  • The Java class ArrayList can be used to represent
    a Stack, Queue, Deque and other ADTs

53
Lecture 4 Interfaces as ADTs
  • Consider again interfaces
  • Specify a set of methods, or, more generally a
    set of behaviors or abilities
  • Do not specify how those methods are actually
    implemented
  • Do not even specify the data upon which the
    methods depend
  • These fit reasonably well with ADTs
  • ADTs DO specify the data, but we can infer much
    about the data based on the methods

54
Lecture 4 Interfaces as ADTs
  • The text will typically use interfaces as ADTs
    and classes as ADT implementations
  • Using the interface we will have to rely on
    descriptions for the data rather than actual data
  • The data itself is left unspecified and will be
    detailed in the class(es) that implement the
    interfaces
  • This is ok since the data is typically specific
    to an implementation anyway
  • Ex ADT Stack
  • Push an object onto the top of the Stack
  • Pop an object off the top of the Stack
  • At this (ADT) level we don't care how the data is
    actually represented, as long as the methods work
    as specified

55
Lecture 4 ADTs for Collections of Data
  • Many ADTs (especially in this course) are used to
    represent collections of data
  • Multiple objects organized and accessed in a
    particular way
  • The organization and access is specified by the
    ADT
  • Done through interfaces in Java
  • The specific implementation of the data and
    operations can be done in various ways
  • Done through classes in Java
  • We will examine many of these this term!

56
Lecture 4 ADT Bag
  • Consider our first detailed ADT the Bag
  • Think of a real bag in which we can place things
  • No rule about how many items to put in
  • No rule about the order of the items
  • No rule about duplicate items
  • No rule about what type of items to put in
  • However, we will make it homogeneous by requiring
    the items to be the same class or subclass of a
    specific Java type
  • Lets look at the interface
  • See BagInterface.java

57
Lecture 4 ADT Bag
  • Note what is NOT in the interface
  • Any specification of the data for the collection
  • We will leave this to the implementation
  • The interface specifies the behaviors only
  • However, the implementation is at least partially
    implied
  • Must be some type of collection
  • Any implementation of the methods
  • Note that other things are not explicitly in the
    interface but maybe should be
  • Ex What the method should do
  • Ex How special cases should be handled
  • We typically have to handle these via comments

58
Lecture 4 ADT Bag
  • Ex public boolean add(T newEntry)
  • We want to consider specifications from two
    points of view
  • What is the purpose / effect of the operation in
    the normal case?
  • What unusual / erroneous situations can occur and
    how do we handle them?
  • The first point can be handled via preconditions
    and postconditions
  • Preconditions indicate what is assumed to be the
    state of the ADT prior to the method's execution
  • Postconditions indicate what is the state of the
    ADT aftter the method's execution
  • From the two we can infer the method's effect

59
Lecture 4 ADT Bag
  • Ex for add(newEntry) we might have
  • Precondition
  • Bag is in a valid state containing N items
  • Postconditions
  • Bag is in a valid state containing N1 items
  • newEntry is now contained in the Bag
  • This is somewhat mathematical, so many ADTs also
    have operation descriptions explaining the
    operation in plainer terms
  • More complex operations may also have more
    complex conditions
  • However, pre and postconditions can be very
    important for verifying correctness of methods

60
Lecture 4 ADT Bag
  • The second point is often trickier to handle
  • Sometimes the unusual / erroneous circumstances
    are not obvious
  • Often they can be handled in more than one way
  • Ex for add(newEntry) we might have
  • Bag is not valid to begin with due to previous
    error
  • newEntry is not a valid object
  • Assuming we detect the problem, we could handle
    it by
  • Doing a "no op"
  • Returning a false boolean value
  • Throwing an exception
  • We need to make these clear to the user of the
    ADT so he/she knows what to expect

61
Lecture 4 Using a Bag
  • A Bag is a simple ADT, but it can still be useful
  • See examples in text
  • Here is another simple one
  • Generate some random integers and count how many
    of each number were generated
  • There are many ways to do this, but one is with a
    bag
  • See Example4.java
  • Q Is this the most efficient way of doing this?
  • A Hard to tell unless we can see how the Bag is
    implemented
  • Lets do that next!

62
Lecture 5 Implementing a Bag
  • Ok, now we need to look at a Bag from the
    implementer's point of view
  • How to represent the data?
  • Must somehow represent a collection of items
    (Objects)
  • How to implement the operations?
  • Clearly, the implementation of the operations
    will be closely related to the representation of
    the data
  • Minimally the data representation will "suggest"
    ways of implementing the operations

63
Lecture 5 Array Implementation of a Bag
  • Let's first consider using an array
  • Makes sense since it can store multiple values
    and allow them to be manipulated in various ways
  • private Object bag // old way
  • private T bag // current way
  • Ok, but is just an array enough?
  • We know the size of an array object, once created
    is fixed
  • We also know that our Bag must be able to change
    in size (with adds and removes)

64
Lecture 5 Array Implementation of a Bag
  • Thus we need to create our array, then keep track
    of how many locations are used with some other
    variable
  • private int numberOfEntries
  • But how big to make the array?
  • What if we run out of room?
  • Note that the above questions are (mostly)
    irrelevant to the client, but are quite important
    to the implementer
  • Two approaches to take
  • Use a fixed size and when it fills it fills
  • Dynamically resize when necessary (transparently)

65
Lecture 5 Fixed Size Array
  • Fixed Size Array
  • Idea
  • Initialize array in the constructor
  • Size is passed in as a parameter
  • Once created, the size is constant as long as the
    list is being used
  • Once array fills, any "add" operations will fail
    until space is freed (through "remove" or
    "clear")
  • Advantage?
  • Easier for programmer to implement

66
Lecture 5 Fixed Size Array
  • Disadvantages
  • ADT user (programmer) may greatly over-allocate
    the array, wasting space
  • Overcompensates to not run out of room
  • Program user (non-programmer) may run out of room
    at run-time
  • If programmer does not do above
  • Neither of these is desirable
  • However, let's briefly look at this
    implementation anyway
  • Much of it will be the same for the dynamic
    structure
  • Only differences are when array fills

67
Lecture 5 Fixed Size Array
  • Let's start with the simple method we have been
    discussing
  • public boolean add (T newEntry)
  • // what do we need to do in the normal case?
  • // what do we do in the abnormal case?
  • Recall our data
  • private T bag
  • private int numberOfEntries
  • Let's figure this out
  • See board

68
Lecture 5 Fixed Size Array
  • Lets look at code from text
  • public boolean add(T newEntry)
  • boolean result true
  • if (isFull())
  • result false
  • else
  • // assertion result is true here
  • bagnumberOfEntries newEntry
  • numberOfEntries
  • // end if
  • return result
  • // end add

69
Lecture 5 Fixed Size Array
  • How about a bit more complicated operation?
  • public boolean remove(T anEntry)
  • What do we need to do here?
  • Think of the normal case
  • Must first find the item
  • Then must remove it
  • How?
  • Think of unusual or special cases
  • Lets work up some code / pseudocode on the board

70
Lecture 5 Fixed Size Array
  • Consider the authors code
  • /
  • Removes one occurrence of a given entry from this
    bag.
  • _at_param anEntry the entry to be removed
  • _at_return true if the removal was successful, or
    false
  • otherwise
  • /
  • public boolean remove(T anEntry)
  • int index getIndexOf(anEntry)
  • T result removeEntry(index)
  • return anEntry.equals(result)
  • // end remove

71
Lecture 5 Fixed Size Array
  • private int getIndexOf(T anEntry)
  • int where -1
  • boolean found false
  • for (int index 0
  • !found (index lt numberOfEntries) index)
  • if (anEntry.equals(bagindex))
  • found true
  • where index
  • // end if
  • // end for
  • return where
  • // end getIndexOf

72
Lecture 5 Fixed Size Array
  • private T removeEntry(int givenIndex)
  • T result null
  • if (!isEmpty() (givenIndex gt 0))
  • result baggivenIndex // entry to
    remove
  • numberOfEntries--
  • baggivenIndex bagnumberOfEntries
  • // replace entry to remove with last entry
  • bagnumberOfEntries null
  • // remove reference to last entry
  • // end if
  • return result
  • // end removeEntry

73
Lecture 5 Fixed Size Array
  • Approach to implementing the other methods should
    be the same
  • What is the method supposed to do?
  • What can go wrong and what do we do about it?
  • Does our code do what we want it to do?
  • See text for discussion of more operations
  • See ArrayBag.java for entire implementation
  • Note Due to publisher restrictions, I am putting
    the authors implementations in a directory that
    is not accessible outside of Pitts domain
  • If you want to access these you must do so from a
    Pitt IP address

74
Lecture 5 Dynamic Size Array
  • Dynamic Size Array
  • Idea
  • Array is created of some initial size
  • Constructor can allow programmer to pass the size
    in, or we can choose some default initial size
  • If this array becomes filled, we must
  • Create a new, bigger array
  • Copy the data from the old array into the new one
  • Assign the new array as our working array
  • Some questions
  • How big to make the new array?
  • How do we copy?
  • What happens to the old array?

75
Lecture 5 Dynamic Size Array
  • How big to make the new array?
  • Clearly it must be bigger than the old array, but
    how much bigger?
  • What must we consider when deciding the size?
  • If we make the new array too small, we will have
    to resize often, causing a lot of overhead
  • If we make the new array too large, we will be
    wasting a lot of memory
  • Let's make the new array 2X the size of the old
    one
  • This way we have a lot of new space but are not
    using outrageously more than we had before
  • We will see more specifically why this was chosen
    later

76
Lecture 5 Dynamic Size Array
  • How do we copy?
  • This is pretty easy just start at the beginning
    of the old array and copy index by index into the
    new array
  • Note that we are copying references, so the
    objects in the new array are the same objects
    that were in the old array
  • What happens to the old array?
  • It is garbage collected
  • Let's try this on the board, then look at code
  • See ResizableArrayBag.java and Example5.java
  • Note how it is largely the same as ArrayBag.java

77
Lecture 5 Dynamic Size Array
  • Let's look in particular at the resizing process
  • Resizing is initiated when an add is performed on
    a list with a full array
  • Only difference from ArrayBag is ensureCapacity()
  • The resizing process is transparent to the user
    of the ResizableArrayBag class
  • For this operation, add() always succeeds

public boolean add(T newEntry) ensureCapacity()
// add new entry after last current
entry bagnumberOfEntries newEntry numberOfE
ntries return true // end add
78
Lecture 5 Dynamic Size Array
  • So what does ensureCapacity() do?
  • Private method to do what we described
  • See Arrays.copyOf() API
  • Note that instance variable numberOfEntries is
    not changed
  • Why?

private void ensureCapacity() if
(numberOfEntries bag.length) bag
Arrays.copyOf(bag, 2 bag.length) // end
ensureCapacity
79
Lecture 5 Contiguous Memory Data Structures
  • Both Bag implementations so far use contiguous
    memory
  • Locations are located next to each other in
    memory
  • Given the address of the first location, we can
    find all of the others based on an offset from
    the first
  • Benefits of contiguous memory
  • We have direct access to individual items
  • Access of item Ai can be done in a single
    operation

0 1 i i1

80
Lecture 5 Contiguous Memory
  • Direct access allows us to use efficient
    algorithms such as Binary Search to find an item
  • Arrays and array-based DS are also fairly simple
    and easy to use
  • Drawbacks of contiguous memory
  • Allocation of the memory must be done at once, in
    a large block as we just discussed
  • If we allocate too much memory we are being
    wasteful
  • If we do not allocate enough, we will run out
  • We have seen how our Bag can resize
    transparently, but recall that this requires
    allocating new memory and copying into it, which
    takes time to do

81
Lecture 5 Contiguous Memory
  • Inserting or deleting data "at the middle" of an
    array may require shifting of the other elements
  • Also requires some time to do
  • We did not need to do this with our Bag, but
    other data structures (ex Lists) may require
    this
  • We will discuss the details of "how much" time is
    required later
  • This deals with algorithm analysis

82
Lecture 6 Linked Data Structures
  • Let's concentrate on the drawbacks of contiguous
    memory
  • Is there an alternative way of storing a
    collection of data that avoids these problems?
  • What if we can allocate our memory in small,
    separate pieces, one for each item in the
    collection
  • Now we allocate exactly as many pieces as we need
  • Now we do not have to shift items, since all of
    the items are separate anyway
  • Draw on board

83
Lecture 6 Linked Data Structures
  • But how do we keep track of all of the pieces?
  • We let the pieces keep track of each other!
  • Let each piece have 2 parts to it
  • One part for the data it is storing
  • One part to store the location of the next piece
  • This is the idea behind a linked-list

firstNode
data
data
data
data
84
Lecture 6 Linked Data Structures
  • Idea of Linked List
  • If we know where the beginning of the list is
  • And each link knows where the next one is
  • Then we can access all of the items in the list
  • Our problems with contiguous memory now go away
  • Allocation can be done one link at a time, for as
    many links as we need
  • New links can be "linked up" anywhere in the
    list, without shifting needed
  • Demonstrate on board

85
Lecture 6 Linked Lists
  • How can we implement linked lists?
  • The key is how each link is implemented
  • As we said, two parts are needed, one for data
    and one to store the location of the next link
  • We can do this with a self-referential data type
  • class Node
  • private T data
  • private Node next
  • A NODE is a common name for a link in a
    linked-list
  • Note why it is called "self-referential"

86
Lecture 6 Singly Linked Lists
  • Linked-List Implementation Variations
  • Singly Linked List
  • The simple linked-list we just discussed is a
    singly-linked list
  • Links go in one direction only
  • We can easily traverse the list from the front to
    the rear
  • We CANNOT go backwards through the list at all
  • This list is simple and (relatively) easy to
    implement, but has the limitations of any "one
    way street"
  • This implementation is developed in Chapter 3

firstNode





87
Lecture 6 Singly Linked Lists
  • There are other variations of linked lists
  • Doubly linked list
  • Circular linked list
  • We will discuss these shortly
  • For now we will keep things very simple

88
Lecture 6 Linked Bag Implementation
  • Let's look at this implementation a bit
  • public class LinkedBagltTgt implements
    BagInterfaceltTgt
  • private Node firstNode
  • private int numberOfEntries
  • private class Node
  • private T data
  • private Node next
  • private Node(T dataPortion)
  • this(dataPortion, null)
  • private Node(T dataPortion, Node nextNode)
  • data dataPortion next nextNode
  • // class Node
  • // class LinkedBag

89
Lecture 6 Node As an Inner Class
  • Why is it done this way?
  • Since Node is declared within LinkedBag, methods
    in LinkedBag can access private declarations
    within Node
  • This is a way to get "around" the protection of
    the private data
  • LinkedBag will be needing to access data and next
    of its Nodes in many of its methods
  • We could write accessors and mutators within Node
    to allow this access
  • However, it is simpler for the programmer if we
    can access data and next directly
  • They are still private and cannot be accessed
    outside of LinkedBag
  • On the downside, with this implementation, we
    cannot use Node outside of the LinkedBag class

90
Lecture 6 Linked Bag Implementation
  • Now let's see how we would implement some of our
    BagInterface methods
  • public boolean add (T newEntry)
  • Node newNode new Node(newEntry) // create
    Node
  • newNode.next firstNode // link it to prev.
    front
  • firstNode newNode // set front to new Node
  • numberofEntries // increment entries
  • return true
  • // method add
  • Compare to add() in the array implementation
  • What is different?
  • Is this a problem?

91
Lecture 6 Linked Bag Implementation
  • Trace on board
  • Try a few adds in example
  • Note insertion is at the front of the bag
  • New node is created and newEntry is put in it
  • New node becomes new front of list, push old
    front back
  • Are there any special cases
  • Ex What if the bag is empty?
  • firstNode will be null
Write a Comment
User Comments (0)
About PowerShow.com