• No results found

6 • Abstract Data Types and Their Implementations

Programming Projects 4

Section 4. 6 • Abstract Data Types and Their Implementations

Definition Aqueueof elements of type T is a finite sequence of elements ofT together with the following operations:

1. Createthe queue, leaving it empty. 2. Test whether the queue isEmpty.

3. Appenda new entry onto the rear of the queue, provided the queue is not full.

4. Serve(and remove) the entry from the front of the queue, provided the queue is not empty.

5. Retrievethe front entry off the queue, provided the queue is not empty.

114

We can also give a precise definition of extended queues as follows.

Definition Anextended queueof elements of typeT is a queue of elements ofT together with the following additional operations:

4. Determine whether the queue isfullor not. 5. Find thesizeof the queue.

6. Serve and retrievethe front entry in the queue, provided the queue is not empty.

7. Clearthe queue to make it empty.

Note that these definitions make no mention of the way in which the abstract data type (stack, queue, or extended queue) is to be implemented. In the past several chapters we have studied different implementations of each of these types, and these new definitions fit any of these implementations equally well.

As we recall fromSection 2.5, in the process of implementing an abstract data type we must pass from the abstract level of a type definition, through a data structures level, where we decide on a structure to model our data type, to an implementation level, where we decide on the details of how our data structure will be stored in computer memory. Figure 4.16 illustrates these stages of refinement in the case of a queue. We begin with the mathematical concept of a sequence and then the queue considered as an abstract data type. At the next level, we choose from the various data structures shown in the diagram, ranging from the physical model (in which all items move forward as each one leaves the head of the queue) to the linear model (in which the queue is emptied all at once) to circular arrays and finally linked lists. Some of these data structures allow further variation in

115

their implementation, as shown on the next level. At the final stage, the queue is coded for a specific application.

Sequence

Stack General list

Physical Linear Circular Linked

Array Array Array Array Simple Circular Array

Airport Line of Mathematical Abstract Data structure Implementation Application Concept Code Algorithm Queue concept data type people with counter with flag simulation with skipped entry with two pointers with tail pointer with two cursors

Figure 4.16. Refinement of a queue

Exercises 4.6

E1. Draw a diagram similar to that ofFigure 4.16showing levels of refinement for a stack.

E2. Give a formal definition of the termdeque, using the definitions given for stack and queue as models. Recall that entries may be added to or deleted from either end of a deque, but nowhere except at its ends.

POINTERS AND PITFALLS

1. Before choosing implementations, be sure that all the data structures and their

116 associated operations are fully specified on the abstract level.

2. In choosing between linked and contiguous implementations, consider the necessary operations on the data structure. Linked structures are more flexible in regard to insertions, deletions, and rearrangement; contiguous structures are sometimes faster.

3. Contiguous structures usually require less computer memory, computer time, and programming effort when the items in the structure are small and the al- gorithms are simple. When the structure holds large records, linked structures usually save space, time, and often programming effort.

4. Dynamic memory and pointers allow a program to adapt automatically to a wide range of application sizes and provide flexibility in space allocation among different data structures. Automatic memory is sometimes more effi- cient for applications whose size can be completely specified in advance.

Chapter 4 Review Questions

155

5. Before reassigning a pointer, make sure that the object that it references will not become garbage.

6. Set uninitialized pointers toNULL.

7. Linked data structures should be implemented with destructors, copy con- structors, and overloaded assignment operators.

8. Use private inheritance to model an “is implemented with” relationship be- tween classes.

9. Draw “before” and “after” diagrams of the appropriate part of a linked struc- ture, showing the relevant pointers and the way in which they should be changed. If they might help, also draw diagrams showing intermediate stages of the process.

10. To determine in what order values should be placed in the pointer fields to

117

carry out the various changes, it is usually better first to assign the values to previously undefined pointers, then to those with valueNULL, and finally to the remaining pointers. After one pointer variable has been copied to another, the first is free to be reassigned to its new location.

11. Be sure that no links are left undefined at the conclusion of a method of a linked undefined links

structure, either as links in new nodes that have never been assigned or links in old nodes that have become dangling, that is, that point to nodes that no longer are used. Such links should either be reassigned to nodes still in use or set to the valueNULL.

12. Always verify that your algorithm works correctly for an empty structure and extreme cases

for a structure with only one node.

13. Avoid the use of constructions such as(p->next)->next, even though they are syntactically correct. A single object should involve only a single pointer deref- multiple dereferencing

erencing. Constructions with repeated dereferencing usually indicate that the algorithms can be improved by rethinking what pointer variables should be declared in the algorithm, introducing new ones if necessary.

REVIEW QUESTIONS

1. Give two reasons why dynamic memory allocation is valuable. 4.1

2. What is garbage?

3. Why should uninitialized pointers be set toNULL? 4. What is an alias and why is it dangerous?

5. Why is it important to return anError_codefrom thepushmethod of a linked 4.2

6. Why should we always add a destructor to a linked data structure? 4.3

7. How is a copy constructor used and why should a copy constructor be included in a linked data structure?

8. Why should a linked data structure be implemented with an overloaded as- signment operator?

9. Discuss some problems that occur in group programming projects that do not 4.5

occur in individual programming projects. What advantages does a group project have over individual projects?

10. In an abstract data type, how much is specified about implementation? 4.6

11. Name (in order from abstract to concrete) four levels of refinement of data specification.

Recursion

5

T

HIS CHAPTER

introduces the study of recursion, the method in which a

problem is solved by reducing it to smaller cases of the same problem.