Object Oriented Analysis and Design Using the UML Version 4_1_ by pptfiles

VIEWS: 4 PAGES: 24

									COP 3540 Data Structures with OOP

         Chapter 5 - Part 2
           Linked Lists

Abstract Data Types and Sorted Lists



                  1/26
             Abstract Data Types
w A wonderful way to deal with data
  structures.
w An ADT is a way of looking at a data
  structure focusing on what it does and NOT
  how it does whatever it is supposed to do.
w We implement an ADT
w Stacks and Queues are examples of ADTs.
w They are ‘concepts’ ; logical data structures.
w Let’s first look how we can have a linked list
  that implements a stack.

                      2/26
         A Stack Implemented by a Linked List
w Can use an array, but no chance to extend it.

w Basic operations: push() and pop() implemented as
  § arr[++top] = newdata; and returnedData = arr[top--];
  § Indexes are checked for stack overflow and stack underflow
    and then adjusted as shown.

w For a Stack: implemented as a linked list, we have
  § theList.insertFirst(data) to add an element onto the stack
     • (looks like a ‘push’)
  § Retrieved data = theList.deleteFirst(). (looks like a pop)

w è The important things: user calls push() and pop()
  for his/her stack operations and has no knowledge
  whether the logical stack is implemented as a physical
  array or as a physical linked list!
                               3/26
                          Client Application
class LinkStackApp
  {
  public static void main(String[] args)
    {
    LinkStack theStack = new LinkStack(); // makes one stack object
          // We know nothing about the stack’s implementation from declaration.

   theStack.push(20);                // push items
   theStack.push(40);

   theStack.displayStack();          // display stack

   theStack.push(60);                // push items      All generic at this point; abstract!
   theStack.push(80);

   theStack.displayStack();          // display stack

   theStack.pop();                   // pop items
   theStack.pop();

   theStack.displayStack();          // display stack
   } // end main()
 } // end class LinkStackApp                    all standard stack operations!!
                                         4/26
         No Changes here…just the nodes…

 class Link (objects of this class are the nodes themselves!)
   {
   public long dData;                 // data item
   public Link next;                // next link in list; note: single link.
// -------------------------------------------------------------
   public Link(long dd)               // constructor
     { dData = dd; }
// -------------------------------------------------------------
   public void displayLink()            // display ourself
     { System.out.print(dData + " "); }
   } // end class Link

// Note: this is really only the data (and the link) and not
the most important methods…
                                    5/26
class LinkStack
   {
   private LinkList theList; ç===============================
//--------------------------------------------------------------
   public LinkStack()                   // constructor
     {                                            Client made an object of
     theList = new LinkList();
     }                                            this class.
//--------------------------------------------------------------
   public void push(long j) // put item on top of stack
     {
     theList.insertFirst(j);
                                                  This is the Interface to the
     }                                            implementation
//--------------------------------------------------------------
   public long pop()                 // take item from top of stack
     {
     return theList.deleteFirst();
     }                                            Can see a generic ‘push’
//--------------------------------------------------------------
   public boolean isEmpty()                       and ‘pop’ etc….
                                            // true if stack is empty
     {
     return ( theList.isEmpty() );                User sees the headers;
     }                                            not the implementation.
//--------------------------------------------------------------
   public void displayStack()
     {
     System.out.print("Stack (top-->bottom): ");  See some implementation
     theList.displayList();
     }
                                                  via the constructor where
                                                  a linked list is created.
//--------------------------------------------------------------
                                                          6/26
   } // end class LinkStack
class LinkList                          Here’s the linked list implementation!
  {
  private Link first;       // ref to first item on list
                                                            Here is your control class for the Linked List –
                                                            your ‘collection class,’ if you will”
  public LinkList()             // constructor
                                                            Note the methods and what they operate on!!
    { first = null; }          // no items on list yet
  public boolean isEmpty()               // true if list is empty
    { return (first==null); }
  public void insertFirst(long dd) // insert at start of list
    {                   // make new link
    Link newLink = new Link(dd);
    newLink.next = first;       // newLink --> old first
    first = newLink;           // first --> newLink //can you draw these steps???
    }
  public long deleteFirst()           // delete first item                                         insertion part
    {                   // (assumes list not empty)                                                deletion part too
    Link temp = first;           // save reference to link
    first = first.next;          // delete it: first-->old next
    return temp.dData;            // return deleted link //can you draw these steps???
    }
  public void displayList()
    {
    Link current = first;     // start at beginning of list
    while(current != null)      // until end of list,           Note: the push is implemented via insertFirst()
       {                                                        The pop is implemented via deleteFirst().
       current.displayLink(); // print data                     which are linked list operations.
       current = current.next; // move to next link
                                                                Logical operations implemented on physical structures
       }
    System.out.println("");
  } // end class LinkList                                 7/26
Discussion of Stack implemented with a Linked List

 w In the LinkStackApp, we pushed two items
   onto the stack
 w Displayed the stack
 w Pushed two more items
 w Displayed stack again
 w Popped two items
 w Displayed the remaining stack.
 w Design: LinkStackApp è LinkStack è
   LinkList è Link.
 w Beautiful part: When client calls push() or
   pop(), generic stack operations, s/he has no
   idea HOW the stack is implemented!!
                           8/26
     A Queue Implemented by a Linked List

w Same song, second verse.
w Idea is to have operations
  § insert() and
  § remove() (both logical queue operations…)
w that are meaningful to the client but yet do
  NOT reveal the design and implementation
  of those operations.
w Consider the following Java code:



                       9/26
class LinkQueueApp (our Main)            Client          Application
  {
  public static void main(String[] args)
    {
    LinkQueue theQueue = new LinkQueue();
         // Could be used to create a number of queues!
         // We know nothing about the queue’s implementation
   theQueue.insert(20);                // insert items
   theQueue.insert(40);

   theQueue.displayQueue();                  // display queue

   theQueue.insert(60);                // insert items
   theQueue.insert(80);

   theQueue.displayQueue();                  // display queue

   theQueue.remove();                      // remove items
   theQueue.remove();
   theQueue.displayQueue();                  // display queue
   } // end main()
 } // end class LinkQueueApp
                                   10/26
// Here are our queue items…(nodes here) No changes                here!
              (simply the nodes themselves)
These are ‘entity’ classes; data classes; objects;

class Link { //this is our queue data and stack data items suitably
modified with two links for a queue object and one link for stack
object. In program2, design one class called Queue and a second:
Stack. (two links because we are building a doubly-linked list for
the queues)

   public long dData;                    // data item
   public Link next;                   // next link in list
// -------------------------------------------------------------
   public Link(long d)                  // constructor
     { dData = d; }
// -------------------------------------------------------------
   public void displayLink()               // display this link
     { System.out.print(dData + " "); }
// -------------------------------------------------------------
                                            11/26
   } // end class Link
  Here’s the Interface to the implementation
class LinkQueue
{
   private FirstLastList theList;
                                                                       This app made an object of this.
//--------------------------------------------------------------       This is interface to implementation:
   public LinkQueue()                      // constructor              Collection Class; Driver….
     {
                theList = new FirstLastList();                         LL_Control class. You will need
      } // end constructor; make a 2-ended list                        one object of this type per queue (4)
//--------------------------------------------------------------
   public boolean isEmpty()                    // true if queue is empty
     {
                return theList.isEmpty();
     }// end IsEmpty()
//--------------------------------------------------------------
   public void insert(long j)               // insert, rear of queue
     {
                theList.insertLast(j);
                                                                                        See logical operation:
     }// end insert()
//--------------------------------------------------------------
                                                                                         insert().
   public long remove()                     // remove, front of queue                   See the implementation
     {                                                                                   which is insertLast().
                return theList.deleteFirst();
     }// end remove()                                                                   Queue goes right to left.
//--------------------------------------------------------------                        Rear of queue is on right
   public void displayQueue()
                                                                                        Front of queue is on left.
     {
     System.out.print("Queue (front-->rear): ");
                                                                                        Insert() in rear (right)
     theList.displayList();                                                             Remove() from front (left)
     }// end displayQueue()                                      12/26                  See drawings ahead…
                 class FirstLastList {
                   private Link first;       // reference to a Link - first item           ç
                   private Link last;         // reference to a Link - last item           ç
                   public FirstLastList() {        // constructor
starting off values: first = null;        // no items on list yet
                     last = null;        // sets these reference values to null.           ç
                     }

               public boolean isEmpty()          // true if no links   Here is the implementation
                { return first==null; }                                  Here’s your queue.
               public void insertLast(long dd) {            // insert at end of list (rear)
                Link newLink = new Link(dd); // make new link è creates object!!
                if( isEmpty() )         // if empty list,
                   first = newLink;       // first --> newLink
                else
                   last.next = newLink;       // old last --> newLink
                last = newLink;            // newLink <-- last // adjusts rear where new node is added.
                                                                                            Here’s the implementation!
                }                                                                           Queue implemented via a
               public long deleteFirst() { // delete first link                              Linked List.

                long temp = first.dData; // (assumes non-empty list)
                if(first.next == null)      // if only one item
                   last = null;         // null <-- last
                first = first.next;       // first --> old next            // adjusting new front as node is removed.
                return temp;
                }
               public void displayList() {
                Link current = first;        // start at beginning
                while(current != null)         // until end of list,
                   {
                   current.displayLink();       // print data        13/26
                   current = current.next; // move to next link
                  First = null
Initially:
                  Last = null




                  First = newLink
                                           123      null
Add first link:
                  Last = newLink


                                                           newlink
                                                                             Link newLink = new Link(dd);
                                                                             // make new link è creates object!!
                                     123      newLink        334      null       last.next = newLink;


Add next link:                         last


                                                           newlink

                                     123      newLink       334       null       last.= newLink;

                                    Front of Queue
                                                               last



                                           Note: insert() is into the rear of the queue.
                                           (This can be implemented either way: where the
                                            ‘rear’ is on the left…)
                                                 14/26
Discussion of Queues Implemented via Linked Lists
w Again, merely implementing a queue using a linked
  list data structure instead of an array.

w Note that linkStack and linkQueue          è stacks
  and queues are conceptual entities.
w They are the interfaces to the real implementations.
w Their implementations represent the physical
  realization of these conceptual entities.

w Choice? Array or Linked List?
w Speed is about the same.
w Uncertain size è use linked list
   § (linked list is also more complex…)
                              15/26
                  Data Types and Abstraction
w Abstract Data Types.
  § Primitives types: data with certain characteristics and sets of
    operations that can be performed on that data.
  § In the computer, there are bounds too on primitive data types due to
    the computer’s architecture. (231 -1 for positive ints; -231 for neg ints)
  § User-defined data types (quantitative types)
     • Some can represent numerical goodies consisting of primitive data
        types. (Complex numbers? (2+3i ) Rational numbers? 1/3)
        Operations must be specified. (no division by zero, etc.)
     • Can/Must define their attributes and their operations
  § User-defined data types (non-quantitative types)
     • Consists of user-defined data types / combinations and the user-
        defined operations permissible on them, like getCountry(), etc...

  § Data types are defined to hold certain arrangements of data and
    possess sets of operations acceptable/appropriate to the data.


                                     16/26
Data Types and Abstraction
w “Abstract” è the data description is considered apart from
  whatever implementation might be used to deal with it.

w Classes are abstractions – apart from the individual objects.

w In OOP, we have lots of ADTs. (Think stacks, queues, trees…)
   § Have descriptions of fields and methods
   § Contain NO details regarding these implementations.
      • These are done on purpose to provide uniform interfaces (like
        push() and pop() and insert()… yet provide opportunity for specific
        implementations that are more appropriate is some instances.

   § A client has access to the methods (through the method interface) and
     how to invoke, and what to expect in return. (public void push (int i) )
   § A client is NOT shown how the methods are implemented.
   § Another example: in String objects, we do not know how ‘compareTo’
     is actually implemented. We do know how it works, how to use it, and
     what to expect in return.       17/26
ADTs as a Design Tool           (è Think country classes…)
w Consider what it is you need to do with data.
w Operations. What operations need to be performed on the
  data?
w Access: How do you need to access it?
   § Do you need to access an element via key? in specific sorted order?
     First one in a list, last one in a list?
w THEN decide on the ADT, whose definition is determined by
  the operations you need to perform on the data.

w Decouple the specification of ADT from implementation.
w è Can change the implementation later!
w è This is its beauty! Can always improve implementation.

w Naturally the underlying data structure must make the
  specified operations as efficient as possible.
w Need sequential access? Perhaps a linked list.
w Need random access? A linked list does not provide this.
  An array does if you know the index of the desired array
  element. Array can be sorted easily too.
                                  18/26
Example of a Subsystem (Architectural Design)

w Subsystem: Maintain Credit Profile Subsystem
w Desired Operations:
  §    Create New Profile
  §    Change Profile
                                                                       Maintain Credit Profile Subsystem
  §    Delete Profile
  §    Get Profile
  §    Display Profile, ….
                                     (subsystem realizes the interface)
                                          MCPS - Int
                                         << interface
                                         >>
                                   Create_profile();                       With lots of connections / dependencies, etc.
                                   Change_profile();
                                   Delete_profile();
                                   Get_profile();
                                   Display_profile();

 These are the operations needed. Provided in interface.
 In a subsystem, implementation is provided inside subsystem,19/26
  whose contents is not available to client. Interface, however, is.
                      SORTED Linked LISTS
w Lists where items are in an order.
w Sorted on some key value usually inside the node.
w Can delete via a find() followed by a ‘logical’ delete()

w Can have sorted list in same way as a sorted array.

w Advantages of a sorted linked list over a sorted array
w are those deficiencies found in the processing of arrays:
   § Speed of insertion: ( O(n) )
      • Find place for new item (‘same’ search time as array)
          w But to Insert in linked list: other items don’t need to be moved!!!)
   § Size of list
      • the fact that the size of the list can expand almost
        indefinitely.
w Disadvantage: Cannot do a binary search on a sorted
  linked list.                       20/26
Java Code to Insert an item into a Sorted List
 Clearly, there must be a search algorithm to
   find the place where the new item should go.

 insert() routine is in book. (will look at this ahead…)
 Essentially it is a search routine to find the place to
   insert the new list item.

 Remember: when searching (with a goal of inserting
  or deleting) a singly-linked list, you MUST keep
  the location (reference) of ‘previous’ link when
  looking at a ‘current link.’
 Not true for a doubly linked list next set of slides.

                             21/26
Additional Considerations

w When inserting into a sorted list, new entry may
  well be placed logically somewhere within the
  list. Physically? We don’t know / care where…

w Boundary Conditions:
  § But it may be the new ‘first’ element in the list.
  § Could also be ‘last’
w Error Conditions:
  § May also be a duplicate!! (generally not wanted)
  § May not be able to find link if we are to ‘change’

w Let’s look at the unique code:
                            22/26
class SortedList {
  private Link first;               // ref to first item
  public SortedList()                     // constructor
     { first = null; }
  public boolean isEmpty()                      // true if no links
     { return (first==null); }
  public void insert(long key) { // insert, in order
     Link newLink = new Link(key); // make new link
     Link previous = null;              // start at first
     Link current = first;
     while(current != null && key > current.dData) {                // or key > current,
        previous = current;                                          // note: sort is ‘descending’
        current = current.next;           // go to next item
        } // end while                                                                                         code. Of interest.
     if(previous==null)                // at beginning of list                                       Must find the right spot!!
        first = newLink;             // first --> newLink
     else                      // not at beginning
        {
        previous.next = newLink;             // old prev --> newLink
        newLink.next = current;              // newLink --> old currnt
        } // end else
} // end insert()
public Link remove() { // return & delete first link
                                                            // (assumes non-empty list)
     Link temp = first;              // save first
     first = first.next;          // delete first
     return temp;                   // return value
     }
public void displayList() {
     System.out.print("List (first-->last): ");
     Link current = first;      // start at beginning of list
     while(current != null) { // until end of list,
        current.displayLink(); // print data
        current = current.next; // move to next link
        }
                                                                     23/26
     System.out.println("");
Efficiency of Sorted Linked Lists
  w Inserting and deleting any item in a sorted linked list
    requires O(n) comparisons (that is a number of
    comparisons directly proportional to the number of
    items IN the list) with n/2 being the average.

  w The smallest (minimum item) can be found or deleted
    in O(1) time since it is in the beginning of the list. (or
    end of the list if you maintain ‘first’ and ‘last’ pointers.)

  w è If access is frequently in the beginning, this is
    good and if inserting is not done a lot or the speed is
    not critical, sorted linked lists are pretty effective.

  w Using the notion of a sorted list, realize that a priority
    queue might be implemented by a sorted linked list.
                                24/26

								
To top