To save content items to your account,
please confirm that you agree to abide by our usage policies.
If this is the first time you use this feature, you will be asked to authorise Cambridge Core to connect with your account.
Find out more about saving content to .
To save content items to your Kindle, first ensure no-reply@cambridge.org
is added to your Approved Personal Document E-mail List under your Personal Document Settings
on the Manage Your Content and Devices page of your Amazon account. Then enter the ‘name’ part
of your Kindle email address below.
Find out more about saving to your Kindle.
Note you can select to save to either the @free.kindle.com or @kindle.com variations.
‘@free.kindle.com’ emails are free but can only be saved to your device when it is connected to wi-fi.
‘@kindle.com’ emails can be delivered even when you are not connected to wi-fi, but note that service fees apply.
The transformation of your client's ideas about his proposed system into the physical, delivered system is a long one. If this transformation is to be at all manageable, it needs to be tackled as a sequence of stages, each bringing you closer to your destination.
The simplest model of the software development process is a purely sequential one with each succeeding stage following on in serial fashion from the previous one. Such a model could serve for a small one-man project but a better approximation to reality is contained in the so-called ‘cascade’ or ‘waterfall’ model suggested in figure 2.1. This recognises that it is generally necessary – even desirable – for the stages to overlap and even repeat.
It is normally customary at this point to talk of the software development ‘lifecycle’ and to draw a diagram along the lines of figure 2.2. This custom is based on the premise that the original development of a system from scratch has the same underlying sequence of events as the enhancement or correction of a system: inception, definition, design, implementation and acceptance. Superficially this is true but the similarity is slight and the generalisation at times unhelpful.
In this book we prefer to talk about the ‘development path’ and ‘maintenance cycles’ and to draw the ‘b-diagram’ along the lines of figure 2.3. This reflects reality more closely. The development path, starting from nothing more than a desire for a system, stands alone.
Given the task of developing a software system, how does one go about it? To start the building of a system of a thousand or maybe a million delivered lines of source code is a daunting (if exciting) prospect. No one should begin without a very clear idea about how the development is to be undertaken and how the quality of its output is to be assessed.
Turning this around we can say that anyone undertaking software development, on no matter what scale, must be strongly advised to establish a methodology for that development – one or more techniques that, by careful integration and control, will bring order and direction to the production process.
To paraphrase Freeman 1982: every software development organisation already has some methodology for building software systems. However, while some software is developed according to modern practices of software development, most of it is still built in an ad hoc way. So it is best to talk about software development techniques and methodologies in terms of changing current practices, replacing them with new techniques that improve the process of software development and the quality of the resulting products.
There is of course a dilemma here for us as system developers: technique X may offer us potential gains such as reduced development time, reduced costs, increased reliability, quality etc, but in adopting it we also incur the risks arising from the fact that we may be unfamiliar with technique X, it might not be suitable for the system we have to develop, and it might not suit our staff and their skills.
In Chapter 2 we considered a very simple data structure, the linked-linear list; and in Chapter 3 we moved on to binary trees. In this chapter we look at two much more general structures.
Firstly we shall consider trees in which nodes may have more than two branches, and in which the number of branches may vary from node to node. For want of a better name we shall call them n-ary trees.
Secondly we shall consider even more general structures which arise when more than one branch leads into a node. These structures are called directed graphs. Clearly they are more general than n-ary trees, which, therefore, may be regarded as a special case.
B-trees
We consider first the n-ary tree, and, in this section, its use in searching applications. Such trees are usually called B-trees, a convention we shall follow.
When we discussed binary trees in Chapter 2 we noted that searching, insertion and deletion were all O(log n), provided that the tree remained balanced. Although we did not discuss the topic of balance in much detail there, we referred the reader to a number of relevant techniques. B-trees arise in this connection too, though here we shall approach them from a different point of view.
Let us imagine first of all that we have a sequence of variable-length items in the store with an item with an infinite key placed at the end.
Recursion is the Cinderella of programming techniques where languages such as Pascal are concerned. All primers mention it, of course, but generally devote only a few pages to it. Rohl and Barrett's Programming via Pascal is one of the more generous: it contains one chapter of 12 pages on the subject!
Books appropriate to second courses in programming, such as those by Wirth (1976), Alagic & Arbib (1978), and the more modern data structures texts, have helped considerably; but currently there is no book devoted to the use of recursion in Pascal or similar languages.
And yet this used not to be the case: Barron's delightful little book Recursive Techniques in Programming was published in 1968! Sadly it is now out of print, and in any event was beginning to show its age. Recursion via Pascal is the author's attempt to fill this gap.
Of course, in functional programming, recursion has received its full due, since it is quite often the only repetitive construct, and this area is fairly well served with text-books. In Recursion via Pascal, most of the examples are procedures rather than functions, partly because that is the usual Pascal style and partly because we want to give examples which actually do something, like drawing the cover motif of this series, instead of merely having a value. Reading one of the functional texts after finishing this book would provide an alternative perspective.
We are going to finish our study of recursion in Pascal programming by seeing how to eliminate it. This may seem a curious thing to do given that for seven chapters we have strongly pressed the case for using recursion, but there are a number of reasons for doing so.
Firstly, it may be that the system we are using does not allow recursion. Such a restriction will not arise with Pascal, of course, but sometimes we are obliged to write in Fortran where such a restriction is part of the language definition. If we can translate a recursive procedure into a non-recursive one, then we can still retain the advantages of designing our programs recursively.
Secondly, where there are two or more forms of recursion in a procedure, its readability may be improved by the removal of one of the recursive aspects. We discussed this idea in Chapter 2 and used it in Chapters 5 and 6. For improved readability, the recursion to be eliminated must be of the preorder, linear type.
Thirdly, we may have tight space constraints or very tight time constraints and it may be that the replacement of a recursive procedure by an iterative one allows us to satisfy those constraints.
Finally, and most importantly, we may wish to consider the elimination of recursion purely to increase our understanding of recursive procedures.
One of the achievements of modern science has been the realization that very few things in the world are completely static. The behaviour of many systems, both organic and synthetic, is influenced greatly by environmental changes. This interaction between a system and its environment can be vastly complicated and yet it is an area that we must try to understand if we are going to be in a position to predict the behaviour of the system and its effect on its environment.
The particular type of analysis that we present here is based on techniques that are generally referred to as algebraic. In some cases we will draw on established algebraic results but in general it is a new type of algebra that has arisen from a desire to understand the behaviour of a system in an environment. This is perhaps the most refreshing aspect of the theory. Here, for a change, is a subject whose motivation can be linked to very real problems in the modern world, a subject that has a short but dramatic history and one which has played a large role in the development of the fundamentals of computer science. However its achievements have not been restricted to this case alone and we hope to illustrate this when we examine the examples at the end of this chapter.
In many of the systems environmental changes alter the behaviour of the system and these changes in behaviour then affect the environment in some way.
In recent years there has been a growing awareness that many complex processes can be regarded as behaving rather like machines. The theory of machines that has developed in the last twenty or so years has had a considerable influence, not only on the development of computer systems and their associated languages and software, but also in biology, psychology, biochemistry, etc. The so-called ‘cybernetic view’ has been of tremendous value in fundamental research in many different areas. Underlying all this work is the mathematical theory of various types of machine. It is this subject that we will be studying here, along with examples of its applications in theoretical biology, etc.
The area of mathematics that is of most use to us is that which is known as modern (or abstract) algebra. For a hundred years or more, algebra has developed enormously in many different directions. These all had origins in difficult problems in the theory of equations, number theory, geometry, etc. but in many areas the subject has taken on its own momentum, the problems arising from within the subject, and as a result there has been a general feeling that much of abstract algebra is of little practical value. The advent of the theory of machines, however, has provided us with new motivation for the development of algebra since it raises very real practical problems that can be examined using many of the abstract tools that have been developed in algebra.