Programming Abstraction in C++ Eric S. Roberts and Julie Zelenski - - PowerPoint PPT Presentation

programming abstraction in c
SMART_READER_LITE
LIVE PREVIEW

Programming Abstraction in C++ Eric S. Roberts and Julie Zelenski - - PowerPoint PPT Presentation

Introduction Stacks Queues Vectors Programming Abstraction in C++ Eric S. Roberts and Julie Zelenski Stanford University 2010 Introduction Stacks Queues Vectors Chapter 11. Linear Structures Introduction Stacks Queues Vectors


slide-1
SLIDE 1

Introduction Stacks Queues Vectors

Programming Abstraction in C++

Eric S. Roberts and Julie Zelenski

Stanford University 2010

slide-2
SLIDE 2

Introduction Stacks Queues Vectors

Chapter 11. Linear Structures

slide-3
SLIDE 3

Introduction Stacks Queues Vectors

Outline

1

Introduction

2

Stacks Array implementation Linked list implementation

3

Queues Array implementation Linked list implementation

4

Vectors

slide-4
SLIDE 4

Introduction Stacks Queues Vectors

Outline

1

Introduction

2

Stacks Array implementation Linked list implementation

3

Queues Array implementation Linked list implementation

4

Vectors

slide-5
SLIDE 5

Introduction Stacks Queues Vectors

Introduction

Linear structures Stack Queue Vector Goals Different (array and linked list) implementations of these linear structures. Introduce template in C++ and polymorphic classes.

slide-6
SLIDE 6

Introduction Stacks Queues Vectors

Outline

1

Introduction

2

Stacks Array implementation Linked list implementation

3

Queues Array implementation Linked list implementation

4

Vectors

slide-7
SLIDE 7

Introduction Stacks Queues Vectors

Template

Changing CharStack to a general Stack template so the stack element can be of any type. Add the following line before a syntactic unit, such as class definition, and before each of the method implementations. template <typename ElemType>

slide-8
SLIDE 8

Introduction Stacks Queues Vectors

Example

Before class definition: template <typename ElemType> class Stack { public: . . . private: #include "stackpriv.h" };

slide-9
SLIDE 9

Introduction Stacks Queues Vectors

Example

Before each of the method implementations: template <typename ElemType> Stack<ElemType>::Stack { capacity = INITIAL_CAPACITY; elements = new ElemType[capacity]; count = 0; } Such classes are said to be polymorphic.

slide-10
SLIDE 10

Introduction Stacks Queues Vectors

Interface

The interface Figure 11-1, pp. 384-385, remains the same as Figure 9-1, p. 320-321, except that the element type char is replaced by ElemType. Include different private data and implementation files to “hide” implementation detail. private: #include "stackpriv.h" #include "stackimpl.cpp"

slide-11
SLIDE 11

Introduction Stacks Queues Vectors

Array implementation

Array implementation (partial): Figure 11-2, Figure 11-3, pp. 386-387. Almost identical to CharStack with dynamic array: Figure 9-2, pp. 323-324, implementation on p. 326.

slide-12
SLIDE 12

Introduction Stacks Queues Vectors

Linked list implementation

No cursor, no dummy cell. The empty stack is represented by the NULL pointer. count for the stack size. The implementation of the methods is straightforward. Figures 11-4 and 11-5, pp. 388-390.

slide-13
SLIDE 13

Introduction Stacks Queues Vectors

struct cellT { ElemType data; cellT *link; }; cellT *list; int count;

slide-14
SLIDE 14

Introduction Stacks Queues Vectors

stackimpl.cpp

template <typename ElemType> void Stack<ElemType>::push(ElemType elem) { cellT *cell = new cellT; cell->data = elem; cell->link = list; list = cell; count++; }

slide-15
SLIDE 15

Introduction Stacks Queues Vectors

stackimpl.cpp

template <typename ElemType> ElemType Stack<ElemType>::pop() { if (isEmpty()) { Error("pop: Empty stack"); } cellT *cell = list; ElemType result = cell->data; list = list->link; count--; delete cell; return result; }

slide-16
SLIDE 16

Introduction Stacks Queues Vectors

Outline

1

Introduction

2

Stacks Array implementation Linked list implementation

3

Queues Array implementation Linked list implementation

4

Vectors

slide-17
SLIDE 17

Introduction Stacks Queues Vectors

Interface

Interface, Figure 11-6, p. 392. Similar to stack, except two operations enqueue adds an element to the end of the queue dequeue removes the first element from the queue

slide-18
SLIDE 18

Introduction Stacks Queues Vectors

Array implementation

Two indexes: head and tail, for easy access to the first and the end elements.

slide-19
SLIDE 19

Introduction Stacks Queues Vectors

Array implementation

Two indexes: head and tail, for easy access to the first and the end elements. To use space efficiently, we “wrap around” the queue from the end of the array back to position 0.

tail

F G H I J K 5 1

1 2 3 4 5 6 7 8 9 head

slide-20
SLIDE 20

Introduction Stacks Queues Vectors

Array implementation

Two indexes: head and tail, for easy access to the first and the end elements. To use space efficiently, we “wrap around” the queue from the end of the array back to position 0.

tail

F G H I J K 5 1

1 2 3 4 5 6 7 8 9 head

This representation is called ring buffer.

slide-21
SLIDE 21

Introduction Stacks Queues Vectors

Array implementation (cont.)

Technique: modular arithmetic %

  • Example. The size of the queue is

(tail + capacity - head) % capacity

slide-22
SLIDE 22

Introduction Stacks Queues Vectors

Array implementation (cont.)

Technique: modular arithmetic %

  • Example. The size of the queue is

(tail + capacity - head) % capacity When tail≥head, the size is tail−head= (tail + capacity - head) % capacity. When tail<head, unwrap the queue and the size is tail+capacity−head.

slide-23
SLIDE 23

Introduction Stacks Queues Vectors

Array implementation (cont.)

To avoid the confusion between an empty queue and a full queue, we limit the number of elements in the queue to one less than the number of elements in the array. Thus the condition for a full queue is size() == capacity - 1 See the method enqueue, p. 307.

slide-24
SLIDE 24

Introduction Stacks Queues Vectors

Array implementation (cont.)

To avoid the confusion between an empty queue and a full queue, we limit the number of elements in the queue to one less than the number of elements in the array. Thus the condition for a full queue is size() == capacity - 1 See the method enqueue, p. 307. Private data, p. 319. Implementation, Figure 11-7, pp. 396-398.

slide-25
SLIDE 25

Introduction Stacks Queues Vectors

Linked list implementation

Two pointers: head and tail. An empty queue is represented by NULL in head. The enqueue must check for the empty queue as a special case.

slide-26
SLIDE 26

Introduction Stacks Queues Vectors

Linked list implementation

Two pointers: head and tail. An empty queue is represented by NULL in head. The enqueue must check for the empty queue as a special case. Similar to the linked list representation of the editor buffer.

slide-27
SLIDE 27

Introduction Stacks Queues Vectors

enqueue

template <typename ElemType> void Queue<ElemType>::enqueue(ElemType elem) { cellT *cellPtr = new cellT; cellPtr->data = elem; cellPtr->link = NULL; if (isEmpty()) { head = cellPtr; } else { tail->link = cellPtr; } tail = cellPtr; count++; }

slide-28
SLIDE 28

Introduction Stacks Queues Vectors

dequeue

template <typename ElemType> void Queue<ElemType>::isEmpty() { return (head == NULL); } template <typename ElemType> ElemType Queue<ElemType>::dequeue() { if (isEmpty()) Error("..."); cellT *cellPtr = head; ElemType result = cellPtr->data; head = cellPtr->link; count--; delete cellPtr; return result; }

slide-29
SLIDE 29

Introduction Stacks Queues Vectors

Outline

1

Introduction

2

Stacks Array implementation Linked list implementation

3

Queues Array implementation Linked list implementation

4

Vectors

slide-30
SLIDE 30

Introduction Stacks Queues Vectors

Introduction

Dynamic array implementation. Similar to the dynamic array representation of the editor buffer, for example, insertion and deletion.

slide-31
SLIDE 31

Introduction Stacks Queues Vectors

Introduction

Dynamic array implementation. Similar to the dynamic array representation of the editor buffer, for example, insertion and deletion. New issues: Check bounds. Square bracket selection. Iterator.

slide-32
SLIDE 32

Introduction Stacks Queues Vectors

Introduction

Dynamic array implementation. Similar to the dynamic array representation of the editor buffer, for example, insertion and deletion. New issues: Check bounds. Square bracket selection. Iterator. Interface, vector.h, Figure 11-11, pp. 405-408. It includes the usual operations and square bracket operator and nested class Iterator.

slide-33
SLIDE 33

Introduction Stacks Queues Vectors

vecpriv.h

Figure 11-12, p. 408 static const int INITIAL_CAPACITY = 100; ElementType *elements; int capacity; int count; void expandCapacity(); Similar to the array editor buffer, p. 347.

slide-34
SLIDE 34

Introduction Stacks Queues Vectors

Check bounds

template <typename ElemType> void Vector<ElemType>::insertAt(int index, ElemType elem) { if (count == capacity) expandCapacity(); if (index < 0 || index > count) { Error("insertAt: index out of range"); } for (int i = count; i > index; i--) { elements[i] = elements[i-1]; } elements[index] = elem; count++; }

slide-35
SLIDE 35

Introduction Stacks Queues Vectors

Implementing selection brackets

Redefine operators for a particular class using the keyword

  • perator.

Return by reference using an &, so values can be assigned to an element selected using square brackets, for example, vec[i] = vec[i - 1].

template <typename ElemType> ElemType & Vector<ElemType>::operator[] (int index) { if (index < 0 || index >= count) { Error("Vector selection index out of range"); } return elements[index]; }

slide-36
SLIDE 36

Introduction Stacks Queues Vectors

Implementing iterators

A nested class, a class within a class. In vector.h: Defining the Iterator class within the Vector class

class Iterator { public: Iterator(); bool hasNext(); ElemType next(); private: Vector *vp; int index; Iterator(Vector *vp); friend class Vector; }; friend class Iterator;

slide-37
SLIDE 37

Introduction Stacks Queues Vectors

Implementing iterators (cont.)

The public section

public: Iterator(); bool hasNext(); ElemType next();

A public (Iterator) constructor, no parameters Two public (Iterator) method prototypes

slide-38
SLIDE 38

Introduction Stacks Queues Vectors

Implementing iterators (cont.)

In the private section

private: Vector *vp; int index; Iterator(Vector *vp); friend class Vector;

Two instance variables, as expected A private constructor (with a parameter, a pointer to Vector) Designate Vector as a friend class, thus Vector class can see the private variables, such as vp and index, and the private constructor Iterator.

slide-39
SLIDE 39

Introduction Stacks Queues Vectors

Implementing iterators (cont.)

Outside the Iterator class, within the Vector class,

friend class Iterator; Iterator iterator();

Designate Iterator as friend class, thus Iterator can see private instance variables such as count. Vector public method prototype iterator.

slide-40
SLIDE 40

Introduction Stacks Queues Vectors

Implementing iterators (cont.)

Idiom: Declaring an iterator

Vector<int>::Iterator iter = vec.iterator();

slide-41
SLIDE 41

Introduction Stacks Queues Vectors

Implementing iterators (cont.)

Idiom: Declaring an iterator

Vector<int>::Iterator iter = vec.iterator();

Implementation of Vector method iterator:

template <typename ElemType> typename Vector<ElemType>::Iterator Vector<ElemType>::iterator() { return Iterator(this); }

It calls Iterator private constructor passing this as the parameter and returns an object of Iterator class.

  • Note. Vector can see Iterator private constructor.
slide-42
SLIDE 42

Introduction Stacks Queues Vectors

Implementing iterators (cont.)

Implementation of Iterator private constructor

template <typename ElemType> Vector<ElemType>::Iterator::Iterator(Vector *vp) { this->vp = vp; index = 0; }

It sets the Iterator instance variable vp to the parameter and index to 0.

  • Note. Iterator now can see Vector private variables

through its own private variable vp.

slide-43
SLIDE 43

Introduction Stacks Queues Vectors

Implementing vectors

Figure 11-12, p. 408, private data file. Figure 11-13, pp. 409-412, implementation file.

slide-44
SLIDE 44

Introduction Stacks Queues Vectors

Implementing vectors

Figure 11-12, p. 408, private data file. Figure 11-13, pp. 409-412, implementation file.

  • Important. Changes to the content of a vector can invalidate the
  • rder of elements returned by an iterator. For example, the

Vector method insertAt or removeAt can change the content of a vector, whereas Iterator has its own variable

  • index. In general, iterators make sense only if the structure is

static.

slide-45
SLIDE 45

Introduction Stacks Queues Vectors

A note on the typename keyword

The Vector method iterator on p. 411, the keyword typename is required for a type/class that is defined inside a class template when the reference is made outside of the implementation of that class template. Why is it outside? Because C++ considers the return type to be

  • utside the scope of the implementation. You are therefore

required to qualify the name of the type by using the full name Vector<ElemType>::Iterator rather than just Iterator. You must also precede the return type with the keyword typename because this type/class is defined within a template. See p. 437, for the typename keyword.