Title: A Generic List Class and Linked Lists
1A Generic List Class and Linked Lists
- Andy Wang
- Data Structures, Algorithms, and Generic
Programming
2Lists in Everyday Life
- Shopping list
- To-do list
- Dave Lettermans top 10 list
- My cats revenge list
- Shopping vector?
- What if you want to insert an item?
3List Wish List
- Insert an element
- Remove an element
- Remove all items
- Assignment operator
- Comparison operators
- Constructors/destructors
- Generic class
- Convenient way to iterate through the list
4Iterator
- Motivating example
- char A10 a, b, c, j
- char j
- for (j A j ! A 10 j)
- cout ltlt j ltlt endl
-
5Iterator
- A generalized model
- A way to initialize at the front and back of a
list - A way to move to the next or previous position
- A way to detect the end of an iteration
- A way to retrieve the current value
- A way to compare two iterators at the same
location
6List Iterator Wish List
- Return the first item
- Return the last item
- Return the current item
- Increment to the next item
- Decrement to previous item
- Detect the end of an iteration
- Compare iterators for equality
- Generic class
7List Public Interface
- Read-only accessor functions
- unsigned int Size() const
- int Empty() const
8List Public Interface (2)
- Locating places on the list
- Iterator Begin() const
- Iterator End() const
- Accessing values on the list
- T Front() const
- T Back() const
9List Public Interface (3)
- Write functions
- int PushFront(const T t)
- int PushBack(const T t)
- int PopFront()
- int PopBack()
- int Insert(Iterator I, const T t)
- int Remove(Iterator I)
- unsigned int Remove(const T t)
- void Clear()
10List Public Interface (4)
- Constructors and destructor
- TList()
- TList()
- TListltTgt operator(const TListltTgt L)
- TList(const TListltTgt L)
- Terminology support
- typedef T value_type
- typedef TListIteratorltTgt Iterator
11List Public Interface (5)
- Non-member functions
- int operator(const TListltTgt L1, const
TListltTgt L2) - int operator!(const TListltTgt L1, const
TListltTgt L2) - ostream operatorltlt(ostream os, const TListltTgt
L)
12List Complexity Requirements
- O(1) Runtime complexity
- Default Constructor
- PushFront(t), PushBack(t), Insert(I, t)
- PopFront(), PopBack(), Remove(I, t)
- Begin(), End()
- Front(), Back()
- Empty()
13List Complexity Requirements (2)
- O(Size()) Runtime complexity
- Copy constructor
- Assignment operator
- Destructor
- Size()
- Clear()
- Remove(t)
14List Iterator Public Interface
- Read-only operators
- int operator(const iterator I2) const
- int operator!(const iterator I2) const
- T operator() const // return a reference to
current value - int Valid() const // Iterator is pointing to a
valid element - Write operators
- iterator operator(const iterator I)
- iterator operator() // prefix
- iterator operator(int) // postfix
- iterator operator--() // prefix
- iterator operator--(int) // postfix
- O(1) requirement for space and time
15Using List
- TListltStringgt KittyVengenceList
- KittyVengenceList.PushFront(toe biting)
- toe biting
- KittyVengenceList.PushBack(carpet littering)
- toe biting, carpet littering
- KittyVengenceList.PushFront(midnight howling)
- midnight howling, toe biting, carpet
littering - KittyVengenceList.PushBack(toilet drinking)
- midnight howling, toe biting, carpet
littering, toilet drinking - TListltStringgtIterator I
- for (I KittyVengenceList.Begin() I !
KittyVengenceList.End() I) - // print list with ltlt
-
16List Insertion
- Insert furniture scratching after toe biting
- // sequential search
- for (I KittyVengenceList.Begin() I.Valid()
I) - if (toe biting I)
- break
-
-
- KittyVengenceList.Insert(I, furniture
scratching) - midnight howling, toe biting, furniture
scratching, carpet littering, toilet
drinking - // what happens if toe biting is not on the
list?
17Remove all copies of t from List
- TListltStringgtIterator I
- for (I KittyVengenceList.Begin() I.Valid())
- if (t I)
- KittyVengenceList.Remove(I)
- else
- I
-
-
18List and List Iterator
- Conceptual relationship
- Iterator L1
- begin current end
- List A, B, C, D, E, F
- begin current end
- Iterator L2
19List Implementation Plan
- ListElement
- Pointers to the previous and next element
- Value
- Defined within the List class, with limited scope
- class ListElement
- // data
- ListElement prev
- ListElement next
- T value
- // constructor
- ListElement(const T t) value(t)
-
20List Implementation Plan (2)
- Protected data
- Pointers to the first and the last element of the
list - Number of list elements
- template lttypename Tgt
- class List
- protected
- ListElement first
- ListElement last
- unsigned int size
- public
-
21Three Perspectives of List
- Client view
- List interface
- ListIterator interface
- Implementation view
- Sequentially ordered list elements
- System view
- List elements connected by pointers
22List Iterator Implementation Plan
- Protected data
- Pointer to the current list element
- template lttypename Tgt
- class ListIterator
- protected
- ListElement curr
- public
- ListIterator operator()
-
23Iterator operator()
- Set curr to the next list element
- template lttypename Tgt
- ListIteratorltTgt
- ListIteratorltTgtoperator()
- curr (curr).next // curr-gtnext
- return this
24Common Implementation Pitfalls
- Forget to update first, last, and size
- Forget to handle special cases
- Empty list
- List with one element
- List with more than one elements
25Debugging Tips
- Best debugging tools
- YOUR BRAIN
- Careful analysis and design
- Writing code for readability and
self-documentation - Best times to debug
- DESIGN TIME
- Coding time
26Defining class TListltTgt
- template lttypename tgt
- class TList
- friend class TListIteratorltTgt
- public
- typedef t value_type
- typedef TListIteratorltTgt Iterator
- // constructors and destructor
- TList()
- TList()
- TList(const TListltTgt L)
- TListltTgt operator(const TListltTgt L)
- // Read-only accessor functions
- unsigned int Size() const
- int Empty() const
- T Front() const
- T Back() const
- Iterator Begin() const
27Defining class TListltTgt (2)
- // Write routines
- int PushFront(const T t)
- int PushBack(const T t)
- int PopFront()
- int PopBack()
- int Insert(Iterator I, const T t)
- int Remove(Iterator I)
- unsigned int Remove(const T t)
- void Clear()
28Defining class TListltTgt (3)
- protected
- class TListElement
- friend class TListltTgt
- friend class TListIteratorltTgt
- // data
- T value
- TListElement prev
- TListElement next
- TListElement(const T Tval)
-
- ListElement first
- ListElement last
- unsigned int size
- void Clone(const TListltTgt L)
-
29Defining class TListltTgt (4)
- // global scope operators and functions
- template lttypename Tgt
- int operator(const TListltTgt L1, const
TListltTgt L2) - template lttypename Tgt
- int operator!(const TListltTgt L1, const
TListltTgt L2) - tempalte lttypename Tgt
- ostream operatorltlt(ostream os, const TListltTgt
L)
30Defining class TListIteratorltTgt
- Template lttypename Tgt
- Class TListIterator
- friend class TListltTgt
- public
- typedef T value_type
- // constructors
- TListIterator()
- TListIterator(const TListltTgt L)
- tListIterator(const TListIterator I)
- void Initialize(const TListltTgt L)
- void rInitialize(const TListltTgt L)
- // read-only routines
- T Retrieve() const // return reference to
curr - int Valid() const
31Defining class TListIteratorltTgt (2)
- // read-only operators
- int operator(const TListIterator I2) const
- int operator!(const TListIterator I2) const
- T operator() const // same as retrieve
- // write operators
- TListIteratorltTgt operator(const
TListIteratorltTgt I) - TListIteratorltTgt operator() // prefix
- TListIteratorltTgt operator(int) // postfix
- TListIteratorltTgt operator--() // prefix
- TListIteratorltTgt operator--(int) // postfix
- protected
- TListltTgtTListElement curr
-
32Implementing class TListltTgt
- Helper functions
- template lttypename Tgt
- void TListltTgtClear()
- // deletes all list elements in the TList
- // and set data members to 0
-
- template lttypename Tgt
- void TListltTgtClone(const TListltTgt L)
- // makes this a clone of L
- // first copy the static data and initialize the
pointers - // then the dynamic data in the non-empty case
33Implementing class TListltTgt (2)
- Constructors
- template lttypename Tgt
- TListltTgtTListElementTListElement(const T t)
value(t), prev(0), next(0) -
- template lttypename Tgt
- TListltTgtTList() first(0), last(0), size(0)
-
- template lttypename Tgt
- TListltTgtTList(const TListltTgt L)
- Clone(L)
-
34Implementing class TListltTgt (3)
- Destructor
- template lttypename Tgt
- TListltTgtTList()
- Clear()
-
35Implementing class TListltTgt (4)
- Read-only functions
- template lttypename Tgt TListIteratorltTgt
TListltTgtBegin() const - Iterator I
- I.curr first
- return I
-
- template lttypename Tgt void TListltTgtDisplay(ostre
am os, char ofc) const - TListltTgtIterator I
- if (ofc \0)
- for (I Begin() I.Valid() I)
- os ltlt I
-
- else
- for (I Begin() I.Valid() I)
- os ltlt I ltlt ofc
-
-
36Implementing class TListltTgt (5)
- Read-only functions
- template lttypename Tgt
- ostream operatorltlt(ostream os, const TListltTgt
L2) - L2.Display(os)
- return os
37Implementing class TListltTgt (6)
- Read-only functions
- template lttypename Tgt
- int operator(const TListltTgt L1, const
TListltTgt L2) - if (L1.Size() ! L2.Size())
- return 0
-
- for (TListltTgtIterator I1(L1), I2(L2)
- I1.Valid() I2.Valid
- I1, I2)
- if (I1 ! I2)
- return 0
-
-
- return 1
-
38Implementing class TListltTgt (7)
- Write functions
- template lttypename Tgt
- int operator(const TListltTgt L)
- if (this ! L)
- Clear()
- Clone(L)
-
- return this
-
39Implementing class TListltTgt (8)
- Insert
- template lttypename Tgt
- int TListltTgtInsert(TListIteratorltTgt I, const
T t) - // call the Push methods when they apply
- // Insert at back if iterator is not valid
- // insert at front if iterator is at front
- // iterator is valid and not at front
- // 1. create a new element
- // 2. link new element into the list
- // 3. adjust size (if present)
- // 4. leave I at new entry and return
-
- template lttypename Tgt
- TListIteratorltTgt TListltTgtInsert(const T t)
- TListIteratorltTgt I End()
- Insert(I, t)
- return I
40Implementing class TListltTgt (9)
- Remove
- template lttypename Tgt int TListltTgtRemove(TListIt
eratorltTgt I) - // call the Pop methods when they apply
- // make sure of consistent interaction with ends
of list - // first deal with the invalid iterator case
- // for a valid iterator and non-void list
- // deal with cases where I.curr first or last
- // at this point, we are removing a link thats
neither first nor last - // 1. remember list element to be removed, and
advance iterator - // 2. unlink old list element from the list
- // 3. delete old list element, adjust size and
return -
- template lttypename Tgt int TListltTgtRemove(const
T t) - // use iterator I and call Remove(I)
- // be sure to take into account the similarity
of Remove(I) and I -
41Implementing class TListIteratorltTgt
- Helper function
- template lttypename Tgt
- TListIteratorltTgtInitialize(const TListltTgt L)
- curr L.first
-
- template lttypename Tgt
- TListIteratorltTgtrInitialize(const TListltTgt L)
- curr L.last
-
42Implementing class TListIteratorltTgt (2)
- Constructors
- template lttypename Tgt
- TListIteratorltTgtTListIterator() curr(0)
-
- template lttypename Tgt
- TListIteratorltTgtTListIterator(const TListltTgt
L) - Initialize(L)
-
- template lttypename Tgt
- TListIteratorltTgtTListIterator(const
TListIteratorltTgt I) curr(I.curr)
43Implementing class TListIteratorltTgt (3)
- Read-only functions
- template lttypename Tgt
- int TListIteratorltTgtValid() const
- return curr ! 0
-
- template lttypename Tgt
- T TListIteratorltTgtRetrieve() const
- if (curr 0)
- stdcerr ltlt TListIterator invalid
dereference ltlt endl - exit(EXIT_FAILURE)
-
- return curr-gtvalue
44Implementing class TListIteratorltTgt (4)
- Operator functions
- template lttypename Tgt
- T TListIteratorltTgtoperator() const
- return curr-gtvalue
-
- template lttypename Tgt
- int TListIteratorltTgtoperator(const
TListIteratorltTgt I2) const - if (curr I2.curr)
- return 1
-
- return 0