CS 228 meeting -*- Outline -*- * Overview of Structured ADTs (HR 4.2) ** example structured ADTs *** Arrays (4.3) give picture don't make a big deal out of the template notation can generalize indexes to any set isomorphic to integers, but to keep it simple, don't ---------------------------- ARRAYS Array DOMAIN: 1. set of contiguous legal index values 2. map from the index values to ItemType values (homogeneous) STRUCTURE: linear, direct access OPERATIONS: Array(int lb, int ub, ItemType init); // MODIFIES: self // POST: legal index values // are lb..ub, // && for all i in lb..ub // the map is from i to init void Store(int i, ItemType v); // PRE: i is a legal index value // MODIFIES: self // POST: the map is the map of // self, except i maps to v ItemType ValueAt(int i) const; // PRE: i is a legal index value // POST: FCTVAL == the value of // the map at index i ---------------------------- this is a generalization of C++ arrays notation: myArr.Store(3, 'c') written as myArr[3] = 'c' in C++ myArr.ValueAt(3) written as myArr[3] in C++ would usually be implemented by C++ built-in arrays, which use built-in memory *** Records (4.4) ------------------------------------- RECORDS Record DOMAIN: 1. set of field names (fname1, ...) 2. a map from field names to values of types T1, ... STRUCTURE: linear, direct access OPERATIONS: Create(T1 v1, T2 v2, ...); // MODIFIES: self // POST: fname1 maps to v1, ... void Store_fname1(T1 v1); // MODIFIES: self // POST: field fname1 maps to v1 T1 Value_fname1() const; // POST: FCTVAL == value at fname1 void Store_fname2(T1 v1); // MODIFIES: self // POST: field fname1 maps to v1 T2 Value_fname2() const; // POST: FCTVAL == value at fname2 ------------------------------------- HR take the field names as arguments The C++ notation for these is r.fname1 = v1 // r.Store_fname1(v1) r.fname1 // r.Value_fname1() *** Lists give picture linear, sequential access in contrast to arrays, can have varying length, and *easier to insert and delete* items access uses a "list cursor" (current place in the list) so these are NOT like Scheme lists ------------------------------------- LISTS List DOMAIN: 1. ordered sequence of values of type ItemType 2. cursor, which is a position in the list or 1 beyond the end INVARIANT: the sequence is empty --> the cursor is beyond the end ----------------------------- state the contrapositive of this too ---------------------------- STRUCTURE: linear, sequential access, size varies OPERATIONS: List(); // MODIFIES: self // POST: sequence of values is empty Boolean IsEmpty() const; // POST: FCTVAL == (sequence is empty) Boolean IsFull() const; // POST: FCTVAL == true if no more // items can be stored, false otherwise void Reset(); // PRE: the sequence is not empty // MODIFIES: self // POST: the cursor is at the front Boolean EndOfList() const; // POST: FCTVAL == (cursor beyond end) void Advance(); // PRE: the cursor is not beyond end // MODIFIES: self // POST: cursor points to next item ItemType CurrentItem() const; // PRE: cursor is not beyond end // POST: FCTVAL == item at cursor void InsertBefore(ItemType someItem); // PRE: another item can be stored // MODIFIES: self // POST: self has someItem at cursor // and someItem precedes item at // cursor (if any) void InsertAfter(ItemType someItem); // PRE: another item can be stored // MODIFIES: self // POST: self has someItem at cursor // and someItem follows item at // cursor (if any) void Delete(); // PRE: cursor is not beyond end // MODIFIES: self // POST: item at cursor // is not in the sequence // && cursor at next item (if any) ------------------------------------- -------------------------------- EXAMPLE CLIENT CODE FOR LISTS #include "clist.h" void DelFirst(CharList & letterGroup, char theChar) // PRE: theChar is in the sequence of // letterGroup // MODIFIES: letterGroup // POST: first occurrence of theChar // is removed from letterGroup { } -------------------------------- What initalization? What changes? What stays the same? letterGroup.Reset(); // INV: no char before the current item is theChar while (letterGroup.CurrentItem() != theChar) { letterGroup.Advance(); } // ASSERT: the current item is the first occurrence of char. letterGroup.Delete(); describe some other ways you could use this *** Stacks (4.6) show picture linear, sequential a kind of restricted list: insertions and deletions both at front ------------------------------------ STACKS Stack DOMAIN: a sequence of component values of type ItemType STRUCTURE: linear, LIFO access OPERATIONS: Stack(); // MODIFIES: self // POST: the sequence is empty Boolean IsEmpty() const; // POST: FCTVAL == (sequence is empty) Boolean IsFull() const; // POST: FCTVAL == true if no more // items can be stored, false otherwise void Push(ItemType newItem); // PRE: the sequence isn't full // MODIFIES: self // POST: newItem is the first in the // the sequence, rest is self ItemType Top() const; // PRE: the sequence isn't empty // POST: FCTVAL == first item in // the sequence void Pop(); // PRE: the sequence isn't empty // MODIFIES: self // POST: the sequence is tail of // the sequence in self ------------------------------------ can use two stacks to implement a list... useful for calculator, programming languges (function calls) Work the balanced braces problem (HR programming project 4.2) *** queues (4.7) show picture ----------------------------------- QUEUES Queue DOMAIN: a sequence of values of type ItemType STRUCTURE: linear, FIFO access OPERATIONS: Queue(); // MODIFIES: self // POST: the sequence is empty Boolean IsEmpty() const; // POST: FCTVAL == (sequence is empty) Boolean IsFull() const; // POST: FCTVAL == true if no more // items can be stored, false otherwise void Enqueue(ItemType newItem); // PRE: the sequence isn't full // MODIFIES: self // POST: newItem is the last in the // the sequence, others unchanged ItemType Front() const; // PRE: the sequence isn't empty // POST: FCTVAL == first item in // the sequence void Dequeue(); // PRE: the sequence isn't empty // MODIFIES: self // POST: the sequence is tail of // the sequence in self ----------------------------------- could look at the theatre simulation in $PUB/Headington-Riley/theater.cpp queues commonly used in simulations: programs that model real-world events and report statistics ----------------------------------- PROBLEM Simulate a duplex theatre waiting line, during 30 minutes before movie. Assumptions: - takes 10 seconds to serve a customer - when the queue is too long, customers go away - in 30 minutes before movie starts, customers arrive randomly with 70% chance every 10 seconds - customers choose movie A or B randomly - queue implementation full = line full Output: number of customers to movie A and B number turned away ----------------------------------- the last is questionable, probably better to find out how long line needs to be, and keep track of it (or have queue do that) (this is hematoma of duplication) (eliminating it would be a good example of inheritance :-) work this out on the computer, using the following outline: // theatre.C #include #include "rand2.h" #include "cqueue.h" int main() { // initiaalize state // for each time unit // process customer // get new customer // print statistics } change assumption so that pairs of people come instead of singles *** Sets (4.8) show picture ------------------------------------ SETS Set DOMAIN: a collection of values of ItemType STRUCTURE: nonlinear OPERATIONS: Set(); // MODIFIES: self // POST: the collection is empty Boolean IsEmpty() const; // POST: FCTVAL == (collection empty) Boolean IsFull() const; // POST: FCTVAL == true if no more // items can be stored, false otherwise void Insert(ItemType i); // PRE: the collection isn't full // MODIFIES: self // POST: self == self union {i} void Delete(Itemtype i); // MODIFIES: self // POST: self == self - i Boolean isElt(Itemtype i) const; // POST: FCTVAL == (i is in collection) Set Intersect( Set set2 ) const; // POST: FCTVAL == is a collection of // the elements in both self and set2 Set Union( Set set2 ) const; // POST: FCTVAL == is a collection of // the elements in either self or set2 ------------------------------------ e.g., tracking set of characters read from input (findchar.cpp) in a useful abstraction, would need some way to access the elements ** summary ** linear vs. sequential access ----------------------------------- LINEAR vs. NONLINEAR TYPES def: a structured ADT is *linear* iff whenever it contains 2 or more components: - there is a unique first and last - all others have unique predecessors and successors def: a structured ADT is *non-linear* iff there is no total ordering. ----------------------------------- show pictures from the book. this will show up in having member functions for accessing elements in order (e.g., subscripts) Q: is time linear? space? courses in your major? ** direct vs. sequential access ----------------------------------- DIRECT vs. SEQUENTIAL ACCESS def: a linear ADT has *direct access* iff each component can be accessed in constant (O(1)) time. def: a linear ADT has *sequential access* iff accessing components takes linear (O(n)) time. ----------------------------------- show analogies from the book Q: is time direct access or sequential? a phone book? a library? ------------------------------------------ SUMMARY OF STRUCTURED ADTS I. Product types A. Linear 1. Direct Access a. Homogeneous components - Array b. Heterogeneous components - Record 2. Sequential Access a. General - List b. Last-in, First-out - Stack c. First-in, First-out - Queue B. Nonlinear - Set II. Sum (Coproduct) Types - Variant Records ------------------------------------------ Draw a diagram similar to the one in the book There are other kinds of structured ADTs, and many specialized types falling in these categories (e.g., Ratl) (e.g, trees are non-linear, but different than sets)