cittadelmonte.info Laws Advanced Data Structures By Sahni Pdf

ADVANCED DATA STRUCTURES BY SAHNI PDF

Sunday, May 12, 2019


Advanced Data Structures presents a comprehensive look at the ideas, eBook (EBL) . Structures (Mehta and Sahni ) is a step in the same direction. PDF | On Jan 1, , Ellis Horowitz and others published Fundamentals of Data Structure in C++. Sartaj Sahni at University of Florida To examine and define a data structure, following the stages below will ensure . the new priority queues with advanced heap implementations as well as and with. Handbook of data structures and applications / edited by Dinesh P. Mehta and Sartaj Sahni. Although there are several advanced and specialized . Sartaj Sahni is a Distinguished Professor and Chair of Computer and Information Sciences.


Advanced Data Structures By Sahni Pdf

Author:ROSANNE CAMINOS
Language:English, Spanish, Dutch
Country:Venezuela
Genre:Lifestyle
Pages:463
Published (Last):09.02.2016
ISBN:383-7-41369-281-3
ePub File Size:23.73 MB
PDF File Size:18.72 MB
Distribution:Free* [*Regsitration Required]
Downloads:39608
Uploaded by: CHRIS

Data Structures, Algorithms And Applications In C++. Pages · · by By Sahni, Sartaj · data structures in c and data structures course, such as CS (T/W/C/S. Data Structures and Algorith. data structure using c notes pdf . Universities Press. COMPUTER SCIENCE. Data Structures,. Algorithms and. Applications IN. • C++. 8 B. Second Edition. SARTAJ SAHNI copyrighted. Handbook of data structures and applications / edited by Dinesh P. Mehta and Sartaj Sahni. p. cm. — (Chapman Although there are several advanced and specialized texts and . Sartaj Sahni is a Distinguished Professor and Chair of Computer and Information Sciences Reference Manual, Addison Wesley,

Often it is regarded as a central course of the curriculum. It is fascinating and instructive to trace the history of how the subject matter for this course has changed. Back in the middle's the course was not entitled Data Structures but perhaps List Processing Languages. Newell, C. Shaw, and H. Simon , LISP 1.

It is often at this point that one realizes that a much better program could have been built. Perhaps you should have chosen the second design alternative or perhaps you have spoken to a friend who has done it better.

It may already be possible to tell if one will be more desirable than the other. The order in which you do this may be crucial. You should consider alternatives. Finally there may be tools available at your computing center to aid in the testing process. This is a phenomenon which has been observed in practice. B and C. The graph in figure 1. The previous discussion applies to the construction of a single procedure as well as to the writing of a large software system.

Each of these is an art in itself. One proof tells us more than any finite amount of testing.

As a minimal requirement. But why bother to document until the program is entirely finished and correct? Because for each procedure you made some assumptions about its input and output. Verification consists of three distinct aspects: For each compiler there is the time they estimated it would take them and the time it actually took. It is usually hard to decide whether to sacrifice this first attempt and begin again or just continue to get the first version working..

Let us concentrate for a while on the question of developing a single procedure which solves a specific task. Before executing your program you should attempt to prove it is correct.

Many times during the proving process errors are discovered in the code. If you have written more than a few procedures.

Different situations call for different decisions. But prior experience is definitely helpful and the time to build the third compiler was less than one fifth that for the first one. If a correct proof can be obtained. The larger the software. Testing is the art of creating sample data upon which to run your program. One such tool instruments your source code and then tells you for every data set: This shifts our emphasis away from the management and integration of the file: If you note them down with the code.

This is another use of program proving. For each subsequent compiler their estimates became closer to the truth. In fact you may save as much debugging time later on by doing a new version now.

Data Structures, Algorithms And Applications In C++

Proofs about programs are really no different from any other kinds of proofs. One thing you have forgotten to do is to document. If you do decide to scrap your work and begin again. The proof can't be completed until these are changed.

If the program fails to respond correctly then debugging is needed to determine what went wrong and how to correct it. Unwarrented optimism is a familiar disease in computing. This is referred to as the bottom-up approach..

Experience suggests that the top-down approach should be followed when creating a program. This method of design is called the top-down approach. One solution is to store the values in an array in such a way that the i-th integer is stored in the i-th array position. One of the simplest solutions is given by the following "from those integers which remain unsorted.

At this level the formulation is said to be abstract because it contains no details regarding how the objects will be represented and manipulated in a computer. Suppose we devise a program for sorting a set of n 1 distinct integers. There now remain two clearly defined subtasks: Each subtask is similarly decomposed until all tasks are expressed within a programming language.

Let us examine two examples of top-down program development. The initial solution may be expressed in English or some form of mathematical notation. Underlying all of these strategies is the assumption that a language exists for adequately describing the processing of data at several abstract levels.

The design process consists essentially of taking a proposed solution and successively refining it until an executable program is achieved. A look ahead to problems which may arise later is often useful.

This latter problem can be solved by the code file: We are now ready to give a second refinement of the solution: If possible the designer attempts to partition the solution into logical subtasks. We observe at this point that the upper limit of the for-loop in line 1 can be changed to n. A j t The first subtask can be solved by assuming the minimum is A i.. From the standpoint of readability we can ask if this program is good.. We first note that for any i. Eventually A n is compared to the current minimum and we are done..

Is there a more concise way of describing this algorithm which will still be as easy to comprehend? Substituting while statements for the for loops doesn't significantly change anything..

There are three possibilities. By making use of the fact that the set is sorted we conceive of the following efficient method: Let us develop another program..

Fundamentals of Data Structures - Ellis Horowitz, Sartaj Sahni.pdf

We assume that we have n 1 distinct integers which are already sorted and stored in the array A 1: Continue in this way by keeping two pointers. Part of the freedom comes from the initialization step. Below is one complete version. In fact there are at least six different binary search programs that can be produced which are all correct.

Note how at each stage the number of elements in the remaining set is decreased by about one half. This method is referred to as binary search. There are many more that we might produce which would be incorrect. For instance we could replace the while loop by a repeat-until statement with the same English condition.

Whichever version we choose. Given a set of instructions which perform a logical operation. The procedure name and its parameters file: As we enter this loop and as long as x is not found the following holds: Actually one of the most useful syntactical features for accomplishing this is the procedure. Unfortunately a complete proof takes us beyond our scope but for those who wish to pursue program proving they should consult our references at the end of this chapter.

Recursion We have tried to emphasize the need to structure a program to make it easier to achieve the goals of readability and correctness. This view of the procedure implies that it is invoked. These recursive mechanisms are extremely powerful. For these reasons we introduce recursion here. This is unfortunate because any program that can be written using assignment.. Most students of computer science view recursion as a somewhat mystical technique which only is useful for some very special class of problems such as computing factorials or Ackermann's function.

What this fails to stress is the fact that procedures may call themselves direct recursion before they are done or they may call other procedures which again invoke the calling procedure indirect recursion. Given the input-output specifications of a procedure. Factorial fits this category. Of course.. When is recursion an appropriate mechanism for algorithm exposition?

One instance is when the problem itself is recursively defined. It implies that we can solve the problem for a set with n elements if we had an algorithm which worked on n. The answer is obtained by printing i a followed by all permutations of b. It is easy to see that given n elements there are n! A is a character string e. Then try to do one or more of the exercises at the end of this chapter which ask for recursive procedures.. Given a set of n 1 elements the problem is to print all possible permutations of this set.

A simple algorithm can be achieved by looking at the case of four elements a. Another instance when recursion is invaluable is when we want to describe a backtracking procedure. Suppose we start with the sorting algorithm presented in this section.

The main purpose is to make one more familiar with the execution of a recursive procedure. We will see several important examples of such structures. This may sound strange. To rewrite it recursively the first thing we do is to remove the for loops and express the algorithm using assignment. This gives us the following set of three procedures. Every place where a ''go to label'' appears.

But for now we will content ourselves with examining some simple. The effect of increasing k by one and restarting the procedure has essentially the same effect as the for loop. Procedure MAXL2 is also directly reculsive. Notice how in MAXL2 the fourth parameter k is being changed.

Thus a recursive call of a file: These two procedures use eleven lines while the original iterative version was expressed in nine lines.

Now let us trace the action of these procedures as they sort a set of five integers When a procedure is invoked an implicit branch to its beginning is made. These have to do with computing time and storage requirements of the algorithms. Performance evaluation can be loosely divided into 2 major phases: Though we will not be discussing how to reach these goals. The second statistic is called the frequency count.

We would like to determine two numbers for this statement. There are many criteria upon which we can judge a program. First consider a priori estimation. Rules are also given there for eliminating recursion. Also in that section are several recursive procedures. The parameter mechanism of the procedure is a form of assignment. The first is the amount of time a single execution will take. The product of these numbers will be the total time taken by this statement.

There are other criteria for judging programs which have a more direct relationship to performance. Hopefully this more subtle approach will gradually infect your own program writing habits so that you will automatically strive to achieve these goals. In section 4. Both of these are equally important. The above criteria are all vitally important when it comes to writing software. It is impossible to determine exactly how much time it takes to execute any command unless we have the following information: Parallelism will not be considered.

One of the hardest tasks in estimating frequency counts is to choose adequate samples of data. All these considerations lead us to limit our goals for an a priori analysis. It is possible to determine these figures by choosing a real machine and an existing compiler.

The anomalies of machine configuration and language will be lumped together when we do our experimental studies. Neither of these alternatives seems attractive. Consider the three examples of Figure 1. Another approach would be to define a hypothetical machine with imaginary execution times.

In both cases the exact times we would determine would not apply to many machines or to any machine.. Each new term is obtained by taking the sum of the two previous terms. Then its frequency count is one.. In the program segment of figure 1. In program b the same statement will be executed n times and in program c n2 times assuming n 1. The program on the following page takes any non-negative integer n and prints the value Fn. In our analysis of execution we will be concerned chiefly with determining the order of magnitude of an algorithm.

Three simple programs for frequency counting. Now 1. To determine the order of magnitude. This means determining those statements which may have the greatest frequency count. The Fibonacci sequence starts as 0. In general To clarify some of these ideas. Below is a table which summarizes the frequency counts for the first three cases. A complete set would include four cases: None of them exercises the program very much. Both commands in step 9 are executed once.

We can summarize all of this with a table. At this point the for loop will actually be entered. These may have different execution counts. Step Frequency Step Frequency 1 1 9 2 2 1 10 n 3 1 11 n-1 4 0 12 n-1 5 1 13 n-1 6 0 14 n-1 7 1 15 1 file: Though 2 to n is only n. Steps 1. Execution Count for Computing Fn Each statement is counted once. O n2 is called quadratic. If we have two algorithms which perform the same task. The reason for this is that as n increases the time for the second algorithm will get far worse than the time for the first.

When we say that the computing time of an algorithm is O g n we mean that its execution takes no more than a constant times g n. If an algorithm takes time O log n it is faster. For example n might be the number of inputs or the number of outputs or their sum or the magnitude of one of them. O n is called linear. O log n. For example. We will often write this as O n. O n3 is called cubic. The for statement is really a combination of several statements.

We write O 1 to mean a computing time which is a constant. These seven computing times. This notation means that the order of magnitude is proportional to n. O n log n is better than O n2 but not as good as O n. Given an algorithm. For small data sets. Using big-oh notation. We will see cases of this in subsequent chapters. Then a performance profile can be gathered using real time calculation.

For exponential algorithms. Another valid performance measure of an algorithm is the space it requires. Often one can trade space for time. For large data sets. Figures 1. On the other hand. This shows why we choose the algorithm with the smaller order of magnitude. Notice how the times O n and O n log n grow much more slowly than the others.. An algorithm which is exponential will work only for very small inputs.

In practice these constants depend on many factors. When n is odd H.. A magic square is an n x n matrix of the integers 1 to n2 such that the sum of every row. Coxeter has given a simple rule for generating a magic square: The statement i. The file: It emphasizes that the variables are thought of as pairs and are changed as a unit. ACM Computing Surveys. For a discussion of tools and procedures for developing very large software systems see Practical Strategies for Developing Large Software Systems.

The Elements of Programming Style by B. Since there are n2 positions in which the algorithm must place a number. For a discussion of the more abstract formulation of data structures see "Toward an understanding of data structures" by J. Thus each statement within the while loop will be executed no more than n2.

The magic square is represented using a two dimensional array having n rows and n column. For this application it is convenient to number the rows and columns from zero to n. For a discussion of good programming techniques see Structured Programming by O. Academic Press. Kernighan and P. For a further discussion of program proving see file: Fundamental Algorithms. Special Issue: The while loop is governed by the variable key which is an integer variable initialized to 2 and increased by one each time through the loop.

Both do not satisfy one of the five criteria of an algorithm. Describe the flowchart in figure 1. Can you think of a clever meaning for S. Concentrate on the letter K first. American Mathematical Society. Discuss how you would actually represent the list of name and telephone number pairs in a real machine. Consider the two statements: Which criteria do they violate? Look up the word algorithm or its older form algorism in the dictionary. Can you do this without using the go to?

Now make it into an algorithm. How would you handle people with the same last name. Determine how many times each statement is executed. Determine when the second becomes larger than the first.. If x occurs. For instance. Given n boolean variables x1. Try writing this without using the go to statement. Implement these procedures using the array facility The rule is: String x is unchanged.

What is the computing time of your method? Strings x and y remain unchanged. NOT X:: Prove by induction: Trace the action of the procedure below on the elements 2. Using the notation introduced at the end of section 1. List as many rules of style in programming that you can think of that you would be willing to follow yourself.

Represent your answer in the array ANS 1: Take any version of binary search. If S is a set of n elements the powerset of S is the set of all possible subsets of S. This function is studied because it grows very fast for small values of m and n. Write a recursive procedure for computing this function. Write a recursive procedure to compute powerset S. Tower of Hanoi There are three towers and sixty four disks of different diameters placed on the first tower.

Monks were reputedly supposed to move the disks from tower 1 to tower 3 obeying the rules: Write a recursive procedure for computing the binomial coefficient as defined in section 1. Analyze the time and space requirements of your algorithm..

Given n. Ackermann's function A m. The pigeon hole principle states that if a function f has n distinct inputs but less than n distinct outputs then there exists two inputs a. Analyze the computing time of procedure SORT as given in section 1. Then write a nonrecursive algorithm for computing Ackermann's function. The disks are in order of decreasing diameter as one scans up the tower. Give an algorithm which finds the values a. Write a recursive procedure which prints the sequence of moves which accomplish this task.

Therefore it deserves a significant amount of attention. It is true that arrays are almost always implemented by using consecutive memory. The array is often the only means for structuring data which is provided in a programming language.

This is unfortunate because it clearly reveals a common point of confusion. For each index which is defined. If one asks a group of programmers to define an array. In mathematical terms we call this a correspondence or a mapping. For arrays this means we are concerned with only two operations which retrieve and store values.

Using our notation this object can be defined as: STORE is used to enter new index-value pairs. In section ARRAYS second axiom is read as "to retrieve the j-th item where x has already been stored at index i in A is equivalent to checking if i and j are equal and if so. There are a variety of operations that are performed on these lists. Notice how the axioms are independent of any representation scheme. If we restrict the index values to be integers.

These operations include: Ace or the floors of a building basement. If we consider an ordered list more abstractly. If we interpret the indices to be n-dimensional. It is only operations v and vi which require real effort. It is not always necessary to be able to perform all of these operations. In the study of data structures we are interested in ways of representing ordered lists so that these operations can be carried out efficiently.

By "symbolic. Let us jump right into a problem requiring ordered lists which we will solve by using one dimensional arrays. This problem has become the classical example for motivating the use of list processing techniques which we will see in later chapters. This we will refer to as a sequential mapping.. We can access the list element values in either direction by changing the subscript values in a controlled way The problem calls for building a set of subroutines which allow for the manipulation of symbolic polynomials.

See exercise 24 for a set of axioms which uses these operations to abstractly define an ordered list.. Insertion and deletion using sequential allocation forces us to move some of the remaining elements so the sequential mapping is preserved in its proper form..

Perhaps the most common way to represent an ordered list is by an array where we associate the list element ai with the array index i. It is precisely this overhead which leads us to consider nonsequential mappings of ordered lists into arrays in Chapter 4. This gives us the ability to retrieve or modify the values of random elements in the list in a constant amount of time. A complete specification of the data structure polynomial is now given. We will also need input and output routines and some suitable format for preparing polynomials as input.

When defining a data object one must decide what functions will be available. However this is not an appropriate definition for our purposes..

For a mathematician a polynomial is a sum of terms where each term has the form axe. The first step is to consider how to define polynomials as a computer structure. MULT poly. Then we would write REM P. Notice the absense of any assumptions about the order of exponents.. Suppose we wish to remove from P those terms having exponent one.

These assumptions are decisions of representation. COEF B. These axioms are valuable in that they describe the meaning of each operation concisely and without implying an implementation. Now we can make some representation decisions. Exponents should be unique and in decreasing order is a very reasonable first decision. Note how trivial the addition and multiplication operations have become. EXP B. Now assuming a new function EXP poly exp which returns the leading exponent of poly.

EXP B file: B REM B. We have avoided the need to explicitly store the exponent of each term and instead we can deduce its value by knowing our position in the list and the degree. But are there any disadvantages to this representation? Hopefully you have already guessed the worst one. The case statement determines how the exponents are related and performs the proper action..

With these insights. EXP B: EXP A. EXP A end end insert any remaining terms in A or B into C The basic loop of this algorithm consists of merging the terms of the two polynomials. Since the tests within the case statement require two terms. COEF A. EXP A.. This representation leads to very simple algorithms for addition and multiplication. But scheme 1 could be much more wasteful. The first entry is the number of nonzero terms. It will require a vector of length In the worst case.

As for storage. Then for each term there are two entries representing an exponent-coefficient pair. Is this method any better than the first scheme? In general. Suppose we take the polynomial A x above and keep only its nonzero coefficients. Basic algorithms will need to be more complex because we must check each exponent before we handle its coefficient. If all of A's coefficients are nonzero.

The assignments of lines 1 and 2 are made only once and hence contribute O 1 to the overall computing time. This is a practice you should adopt in your own coding. The procedure has parameters which are polynomial or array names. The code is indented to reinforce readability and to reveal more clearly the scope of reserved words.

Statement two is a shorthand way of writing r Notice how closely the actual program matches with the original design. Comments appear to the right delimited by double slashes. Three pointers p. Blocks of statements are grouped together using square brackets. The basic iteration step is governed by a while loop. It is natural to carry out this analysis in terms of m and n. To make this problem more concrete. Returning to the abstract object--the ordered list--for a moment.

These are defined by the recurrence relation file: A two dimensional array could be a poor way to represent these lists because we would have to declare it as A m. This hypothetical user may have many polynomials he wants to compute and he may not know their sizes.. This worst case is achieved. Suppose in addition to PADD. Consider the main routine our mythical user might write if he wanted to compute the Fibonacci polynomials. In this main program he needs to declare arrays for all of his polynomials which is reasonable and to declare the maximum size that every polynomial might achieve which is harder and less reasonable.

Taking the sum of all of these steps. He would include these subroutines along with a main procedure he writes himself. This example shows the array as a useful representational form for ordered lists Each iteration of this while loop requires O 1 time.

In particular we now have the m lists a If he declares the arrays too large. Instead we might store them in a one dimensional array and include a front i and rear i pointer for the beginning and end of each list. Since the iteration terminates when either p or q exceeds 2m or 2n respectively.

We are making these four procedures available to any user who wants to manipulate polynomials. At each iteration. For example F 2. Suppose the programmer decides to use a two dimensional array to store the Fibonacci polynomials.

Then the following program is produced. If we made a call to our addition routine. Let's pursue the idea of storing all polynomials in a single array called POLY. Exponents and coefficients are really different sorts of numbers. If the result has k terms. Also we need a pointer to tell us where the next free location is. The array is usually a homogeneous collection of data which will not allow us to intermix data of different types.

Then by storing all polynomials in a single array. A much greater saving could be achieved if Fi x were printed as soon as it was computed in the first loop. Different types of data cannot be accommodated within the usual array concept.. This example reveals other limitations of the array as a means for data representation.

When m is equal to n. We could write a subroutine which would compact the remaining polynomials. It is very natural to store a matrix in a two dimensional array.

A general matrix consists of m rows and n columns of numbers as in figure 2. Such a matrix is called sparse.. We might then store a matrix as a list of 3-tuples of the form i. There may be several such polynomials whose space can be reused.

On most computers today it would be impossible to store a full X matrix in the memory at once. There is no precise definition of when a matrix is sparse and when it is not. Then we can work with any element by writing A i. This comes about because in practice many of the matrices we want to deal with are large.

As computer scientists. A sparse matrix requires us to consider an alternate form of representation. Even worse. As we create polynomials. Such a matrix has mn elements. Now if we look at the second matrix of figure 2. Now we have localized all storage to one array. Example of 2 matrices The first matrix has five rows and three columns.

This demands a sophisticated compacting routine coupled with a disciplined use of names for polynomials. When this happens must we quit?

We must unless there are some polynomials which are no longer needed. Figure 2. But this may require much data movement. In Chapter 4 we will see an elegant solution to these problems. The alternative representation will explicitly store only the nonzero elements. Each element of a matrix is uniquely characterized by its row and column position. Sparse matrix stored as triples The elements A 0. This is where we move the elements so that the element in the i. The transpose of the example matrix looks like 1.

Another way of saying this is that we are interchanging rows and columns. We can go one step farther and require that all the 3-tuples of any row be stored so that the columns are increasing.. The elements on the diagonal will remain unchanged. Now what are some of the operations we might want to perform on these matrices? One operation is to compute the transpose matrix. If we just place them consecutively. In our example of figure 2. We can avoid this data movement by finding the elements in the order we want them.

Since the rows are originally in order. Let us write out the algorithm in full. Since the rows of B are the columns of A. The variable q always gives us the position in B where the next term in the transpose is to be inserted. The assignment in lines takes place exactly t times as there are only t nonzero terms in the sparse matrix being generated. How about the computing time of this algorithm! For each iteration of the loop of lines On the first iteration of the for loop of lines all terms from column 1 of A are collected.

Lines take a constant amount of time. This is precisely what is being done in lines The total time for the algorithm is therefore O nt. Since the number of iterations of the loop of lines is n. This computing time is a little disturbing since we know that in case the matrices had been represented as two dimensional arrays. In addition to the space needed for A and B.. The terms in B are generated by rows. The algorithm for this takes the form: The statement a.

We now have a matrix transpose algorithm which we believe is correct and which has a computing time of O nt. It is not too difficult to see that the algorithm is correct. This is worse than the O nm time using arrays. This gives us the number of elements in each row of B.

We can now move the elements of A one by one into their correct position in B. This algorithm. From this information. Each iteration of the loops takes only a constant amount of time. T j is maintained so that it is always the position in B where the next element in row j is to be inserted.. The computation of S and T is carried out in lines Hence in this representation.

When t is sufficiently small compared to its maximum of nm. In lines the elements of A are examined one by one starting from the first and successively moving to the t-th element. This is the same as when two dimensional arrays were in use. MACH m 6. Associated with each machine that the company produces.

If we try the algorithm on the sparse matrix of figure 2. Suppose now you are working for a machine manufacturer who is using a computer to do inventory control T i points to the position in the transpose where the next element of row i is to be stored. Each part is itself composed of smaller parts called microparts.

The product of two sparse matrices may no longer be sparse. Regarding these tables as matrices this application leads to the general definition of matrix product: We want to determine the number of microparts that are necessary to make up each machine. Once the elements in row i of A and column j of B have been located. Before we write a matrix multiplication procedure. To compute the elements of C row-wise so we can store them in their proper place without moving previously computed elements.

To avoid this. Consider an algorithm which computes the product of two sparse matrices represented as an ordered list instead of an array. This sum is more conveniently written as If we compute these sums for each machine and each micropart then we will have a total of mp values which we might store in a third table MACHSUM m.

An alternative approach is explored in the exercises. Its i. This enables us to handle end conditions i.

C and some simple variables. In addition to the space needed for A. We leave the correctness proof of this algorithm as an exercise. The total maximum increments in i is therefore pdr. It makes use of variables i. In each iteration of the while loop of lines either the value of i or j or of both increases by 1 or i and col are reset.

In addition to all this. The while loop of lines is executed at most m times once for each row of A. When this happens Let us examine its complexity. The variable r is the row of A that is currently being multiplied with the columns of B.

The maximum total increment in j over the whole loop is t2. The maximum number of iterations of the while loop of lines file: At the same time col is advanced to the next column. If dr is the number of terms in row r of A then the value of i can increase at most dr times before i moves to the next row of A.

Since the number of terms in a sparse matrix is variable. It introduces some new concepts in algorithm analysis and you should make sure you understand the analysis. As in the case of polynomials.

Data Structures, Algorithms And Applications In C++ by By Sahni, Sartaj - PDF Drive

The classical multiplication algorithm is: Once again. Lines take only O dr time. There are. MMULT will be slower by a constant factor. A and B are sparse. MMULT will outperform the above multiplication algorithm for arrays.. This would enable us to make efficient utilization of space. Since t1 nm and t2 np. These difficulties also arise with the polynomial representation of the previous section and will become apparent when we study a similar representation for multiple stacks and queues section 3.

If an array is declared A l1: If we have the declaration A 4: Recall that memory may be regarded as one dimensional with words numbered from 1 to m. To describe a data structure in a representation independent way one needs a syntax. This can be seen at the end of section 1. This book also seeks to teach the art of analyzing algorithms but not at the cost of undue mathematical sophistication.

The value of an implementation ultimately relies on its resource utilization: This implies that the student needs to be capable of analyzing these factors. A great many analyses have appeared in the literature, yet from our perspective most students don't attempt to rigorously analyze their programs. The data structures course comes at an opportune time in their training to advance and promote these ideas. For every algorithm that is given here we supply a simple, yet rigorous worst case analysis of its behavior.

In some cases the average computing time is also file: The growth of data base systems has put a new requirement on data structures courses, namely to cover the organization of large files. Also, many instructors like to treat sorting and searching because of the richness of its examples of data structures and its practical application. The choice of our later chapters reflects this growing interest. One especially important consideration is the choice of an algorithm description language.

Such a choice is often complicated by the practical matters of student background and language availability. Our decision was to use a syntax which is particularly close to ALGOL, but not to restrict ourselves to a specific language. This gives us the ability to write very readable programs but at the same time we are not tied to the idiosyncracies of a fixed language. Wherever it seemed advisable we interspersed English descriptions so as not to obscure the main pointof an algorithm.

For those who have only FORTRAN available, the algorithms are directly translatable by the rules given in the appendix and a translator can be obtained see appendix A. On the other hand, we have resisted the temptation to use language features which automatically provide sophisticated data structuring facilities.

We have done so on several grounds. One reason is the need to commit oneself to a syntax which makes the book especially hard to read by those as yet uninitiated. Even more importantly, these automatic featules cover up the implementation detail whose mastery remains a cornerstone of the course. The basic audience for this book is either the computer science major with at least one year of courses or a beginning graduate student with prior training in a field other than computer science.

This book contains more than one semester's worth of material and several of its chapters may be skipped without harm. The following are two scenarios which may help in deciding what chapters should be covered. He would cover chapters one through five skipping sections 2. Then, in whatever time was left chapter seven on sorting was covered. In the first quarter's data structure course, chapters one through three are lightly covered and chapters four through six are completely covered.

The second quarter starts with chapter seven which provides an excellent survey of the techniques which were covered in the previous quarter. Then the material on external sorting, symbol tables and files is sufficient for the remaining time. Note that the material in chapter 2 is largely mathematical and can be skipped without harm. The paradigm of class presentation that we have used is to begin each new topic with a problem, usually chosen from the computer science arena.

Once defined, a high level design of its solution is made and each data structure is axiomatically specified. A tentative analysis is done to determine which operations are critical. Implementations of the data structures are then given followed by an attempt at verifying.

The finishedalgorithm in the book is examined followed by an argument concerning its correctness. Then an analysis is done by determining the relevant parameters and applying some straightforward rules to obtain the correct computing time formula.

In summary, as instructors we have tried to emphasize the following notions to our students: In addition there are two underlying currents which, though not explicitly emphasized are covered throughout. The first is the notion of writing nicely structured programs. For all of the programs contained herein we have tried our best to structure them appropriately.

We hope that by reading programs with good style the students will pick up good writing habits. A nudge on the instructor's part will also prove useful. The second current is the choice of examples. We have tried to use those examples which prove a point well, have application to computer programming, and exhibit some of the brightest accomplishments in computer science. At the close of each chapter there is a list of references and selected readings.

These are not meant to be exhaustive. They are a subset of those books and papers that we found to be the most useful. Otherwise, they are either historically significant or develop the material in the text somewhat further. Many people have contributed their time and energy to improve this book.

For this we would like to thank them. We wish to thank Arvind [sic], T. Gonzalez, L. Landweber, J. Misra, and D.

Wilczynski, who used the book in their own classes and gave us detailed reactions. Thanks are also due to A. Agrawal, M. Cohen, A. Howells, R. Istre, D. Ledbetter, D.

Musser and to our students in CS , CSci and who provided many insights. For administrative and secretarial help we thank M. Eul, G. Lum, J. Matheson, S. Moody, K. Pendleton, and L. To the referees for their pungent yet favorable comments we thank S. Gerhart, T. Standish, and J. Finally, we would like to thank our institutions, the University of Southern California and the University of Minnesota, for encouraging in every way our efforts to produce this book.

Ellis Horowitz Sartaj Sahni Preface to the Ninth Printing We would like to acknowledge collectively all of the individuals who have sent us comments and corrections since the book first appeared.

For this printing we have made many corrections and improvements. October l file: One often quoted definition views computer science as the study of algorithms. This study encompasses four distinct areas: The goal is to study various forms of machine fabrication and organization so that algorithms can be effectively carried out.

At one end are the languages which are closest to the physical machine and at the other end are languages designed for sophisticated problem solving. One often distinguishes between two phases of this area: The first calls for methods for specifying the syntax and semantics of a language.

The second requires a means for translation into a more basic set of commands. Abstract models of computers are devised so that these properties can be studied.

This was realized as far back as by Charles Babbage, the father of computers. An algorithm's behavior pattern or performance profile is measured in terms of the computing time and space that are consumed while the algorithm is processing.

Questions such as the worst and average time and how often they occur are typical. We see that in this definition of computer science, "algorithm" is a fundamental notion. Thus it deserves a precise definition. The dictionary's definition "any mechanical or recursive computational procedure" is not entirely satisfying since these terms are not basic enough.

An algorithm is a finite set of instructions which, if followed, accomplish a particular task. In addition every algorithm must satisfy the following criteria: It is not enough that each operation be definite as in iii , but it must also be feasible.

In formal computer science, one distinguishes between an algorithm, and a program. A program does not necessarily satisfy condition iv. One important example of such a program for a computer is its operating system which never terminates except for system crashes but continues in a wait loop until more jobs are entered.

In this book we will deal strictly with programs that always terminate. Hence, we will use these terms interchangeably. An algorithm can be described in many ways. A natural language such as English can be used but we must be very careful that the resulting instructions are definite condition iii. An improvement over English is to couple its use with a graphical form of notation such as flowcharts.

This form places each processing step in a "box" and uses arrows to indicate the next step. Different shaped boxes stand for different kinds of operations. All this can be seen in figure 1.

The point is that algorithms can be devised for many common activities. Have you studied the flowchart? Then you probably have realized that it isn't an algorithm at all! Which properties does it lack? Returning to our earlier definition of computer science, we find it extremely unsatisfying as it gives us no insight as to why the computer is revolutionizing our society nor why it has made us re-examine certain basic assumptions about our own role in the universe.

While this may be an unrealistic demand on a definition even from a technical point of view it is unsatisfying. The definition places great emphasis on the concept of algorithm, but never mentions the word "data". If a computer is merely a means to an end, then the means may be an algorithm but the end is the transformation of data.

That is why we often hear a computer referred to as a data processing machine. Raw data is input and algorithms are used to transform it into refined data. So, instead of saying that computer science is the study of algorithms, alternatively, we might say that computer science is the study of data: Figure 1. Flowchart for obtaining a Coca-Cola There is an intimate connection between the structuring of data, and the synthesis of algorithms. In fact, a data structure and an algorithm should be thought of as a unit, neither one making sense without the other.

For instance, suppose we have a list of n pairs of names and phone numbers a1,b1 a2,b2 , This task is called searching. Just how we would write such an algorithm critically depends upon how the names and phone numbers are stored or structured. One algorithm might just forge ahead and examine names, a1,a2,a3, This might be fine in Oshkosh, but in Los Angeles, with hundreds of thousands of names, it would not be practical. If, however, we knew that the data was structured so that the names were in alphabetical order, then we could do much better.

We could make up a second list which told us for each letter in the alphabet, where the first name with that letter appeared. For a name beginning with, say, S, we would avoid having to look at names beginning with other letters. So because of this new structure, a very different algorithm is possible. Other ideas for algorithms become possible when we realize that we can organize the data as we wish. We will discuss many more searching strategies in Chapters 7 and 9. Therefore, computer science can be defined as the study of data, its representation and transformation by a digital computer.

The goal of this book is to explore many different kinds of data objects. For each object, we consider the class of operations to be performed and then the way to represent this object so that these operations may be efficiently carried out. This implies a mastery of two techniques: The pedagogical style we have chosen is to consider problems which have arisen often in computer applications. For each problem we will specify the data object or objects and what is to be accomplished. After we have decided upon a representation of the objects, we will give a complete algorithm and analyze its computing time.

After reading through several of these examples you should be confident enough to try one on your own. There are several terms we need to define carefully before we proceed. These include data structure, data object, data type and data representation. These four terms have no standard meaning in computer science circles, and they are often used interchangeably. A data type is a term which refers to the kinds of data that variables may "hold" in a programming language.

With every programming language there is a set of built-in data types. This means that the language allows variables to name data of that type and. Some data types are easy to provide because they are already built into the computer's machine language instruction set. Integer and real arithmetic are examples of this. Other data types require considerably more effort to implement.

In some languages, there are features which allow one to construct combinations of the built-in types. However, it is not necessary to have such a mechanism. All of the data structures we will see here can be reasonably built within a conventional programming language. Data object is a term referring to a set of elements, say D.

Thus, D may be finite or infinite and if D is very large we may need to devise special ways of representing its elements in our computer. The notion of a data structure as distinguished from a data object is that we want to describe not only the set of objects, but the way they are related.

Saying this another way, we want to describe the set of operations which may legally be applied to elements of the data object. This implies that we must specify the set of operations and show how they work. To be more precise lets examine a modest example. The following notation can be used: SUCC stands for successor. The rules on line 8 tell us exactly how the addition operation works.

For example if we wanted to add two and three we would get the following sequence of expressions: In practice we use bit strings which is a data structure that is usually provided on our computers. But however the ADD operation is implemented, it must obey these rules. Hopefully, this motivates the following definition. A data structure is a set of domains , a designated domain , a set of functions and a end.

It is called abstract precisely because the axioms do not imply a form of representation. Our goal here is to write the axioms in a representation independent way. Thus we say that integers are represented by bit strings. We might begin by considering using some existing language.

But at the first stage a data structure should be designed so that we know what it does. Another way of viewing the implementation of a data structure is that it is the process of refining an abstract data type until all of the operations are expressible in terms of directly executable functions. An implementation of a data structure d is a mapping from d to a set of other data structures e. Though some of these are more preferable than others. This division of tasks. This mapping specifies how every object of d is to be represented by the objects of e.

In current parlance the triple is referred to as an abstract data type. Furthermore it is not really necessary to write programs in a language for which a compiler exists. We would rather not have any individual rule us out simply because he did not know or. The triple denotes the data structure d and it will usually be abbreviated by writing In the previous example The set of axioms describes the semantics of the operations. Thus we would have to make pretense to build up a capability which already exists.

First of all. The form in which we choose to write the axioms is important. Instead we choose to use a language which is tailored to describing the algorithms we want to write. The way to assign values is by the assignment statement variable expression. Several cute ideas have been suggested. In addition to the assignment statement. Several such statements can be combined on a single line if they are separated by a semi-colon. Expressions can be either arithmetic..

In order to produce these values. In the boolean case there can be only one of two values.. Most importantly. The meaning of this statement is given by the flow charts: Though this is very interesting from a theoretical viewpoint. S is as S1 before and the meaning is given by It is well known that all "proper" programs can be written using only the assignment.

To accomplish iteration.. If S1 or S2 contains more than one statement. Brackets must be used to show how each else corresponds to one if. So we will provide other statements such as a second iteration statement.

On the contrary. This result was obtained by Bohm and Jacopini. One of them is while cond do S end where cond is as before. Another iteration statement is loop S forever which has the meaning As it stands.

One way of exiting such a loop is by using a go to label statement which transfers control to "label. A more restricted form of the go to is the command exit which will cause a transfer of control to the first statement after the innermost loop which contains it. This looping statement may be a while.. The semantics is easily described by the file: We can write the meaning of this statement in SPARKS as vble fin incr start finish increment 0 do start to finish by increment do while vble..

It has the form where the Si. A variable or a constant is a simple form of an expression. A procedure may be invoked by using a call statement call NAME parameter list Procedures may call themselves.

The else clause is optional. The execution of an end at the end of procedure implies a return. Though recursion often carries with it a severe penalty at execution time. This may be somewhat restrictive in practice. All procedures are treated as external. The expr may be omitted in which case a return is made to the calling procedure. Parameters which are constants or values of expressions are stored into internally generated words whose addresses are then passed to the procedure.

Many such programs are easily translatable so that the recursion is removed and efficiency achieved. The association of actual to formal parameters will be handled using the call by reference rule.

This penalty will not deter us from using recursion. This means that at run time the address of each parameter is passed to the called procedure. This is a goal which should be aimed at by everyone who writes programs. These are often useful features and when available they should be used. We avoid the problem of defining a "format" statement as we will need only the simplest form of input and output..

See the book The Elements of Programming Style by Kernighan and Plauger for more examples of good rules of programming. The command stop halts execution of the currently executing procedure.

Comments may appear anywhere on a line enclosed by double slashes.. An n-dimensional array A with lower and upper bounds li.. We have avoided introducing the record or structure concept. The SPARKS language is rich enough so that one can create a good looking program by applying some simple rules of style. Avoid sentences like ''i is increased by one. It is often at this point that one realizes that a much better program could have been built. But to improve requires that you apply some discipline to the process of creating programs.

Assume that these operations already exist in the form of procedures and write an algorithm which solves the problem according to the requirements.

Designing an algorithm is a task which can be done independently of the programming language you eventually plan to use. One of the criteria of a good design is file: Use a notation which is natural to the way you wish to describe the order of processing. If you have been careful about keeping track of your previous work it may not be too difficult to make changes. You should consider alternatives. In fact.

Can you think of another algorithm?

If so. Make sure you understand the information you are given the input and what results you are to produce the output.

Fundamentals of Data Structures - Ellis Horowitz & Sartaj Sahni

You are now ready to proceed to the design phase. This method uses the philosophy: It may already be possible to tell if one will be more desirable than the other. To understand this process better. The order in which you do this may be crucial. Modern pedagogy suggests that all processing which is independent of the data representation be written out first.

Perhaps you should have chosen the second design alternative or perhaps you have spoken to a friend who has done it better. By postponing the choice of how the data is stored we can try to isolate what operations depend upon the choice of data representation. For each object there will be some basic operations to perform on it such as print the maze.

Try to write down a rigorous description of the input and output which covers all cases. You must now choose representations for your data objects a maze as a two dimensional array of zeros and ones.

Finally you produce a complete version of your first program. If you can't distinguish between the two. You may have several data objects such as a maze.

We hope your productivity will be greater. This happens to industrial programmers as well. The larger the software. The proof can't be completed until these are changed. The previous discussion applies to the construction of a single procedure as well as to the writing of a large software system.

Verification consists of three distinct aspects: Before executing your program you should attempt to prove it is correct.. Unwarrented optimism is a familiar disease in computing. This shifts our emphasis away from the management and integration of the file: One thing you have forgotten to do is to document.

Different situations call for different decisions. One such tool instruments your source code and then tells you for every data set: As a minimal requirement.

Proofs about programs are really no different from any other kinds of proofs. B and C. If the program fails to respond correctly then debugging is needed to determine what went wrong and how to correct it. Testing is the art of creating sample data upon which to run your program.

For each subsequent compiler their estimates became closer to the truth. It is usually hard to decide whether to sacrifice this first attempt and begin again or just continue to get the first version working.

But why bother to document until the program is entirely finished and correct? Because for each procedure you made some assumptions about its input and output. The graph in figure 1. In fact you may save as much debugging time later on by doing a new version now. If you note them down with the code.

Each of these is an art in itself. If you do decide to scrap your work and begin again. For each compiler there is the time they estimated it would take them and the time it actually took. Finally there may be tools available at your computing center to aid in the testing process. Let us concentrate for a while on the question of developing a single procedure which solves a specific task. Many times during the proving process errors are discovered in the code. This is a phenomenon which has been observed in practice.

If you have written more than a few procedures. This is another use of program proving. But prior experience is definitely helpful and the time to build the third compiler was less than one fifth that for the first one. One proof tells us more than any finite amount of testing. If a correct proof can be obtained. This latter problem can be solved by the code file: Each subtask is similarly decomposed until all tasks are expressed within a programming language.

This is referred to as the bottom-up approach. The design process consists essentially of taking a proposed solution and successively refining it until an executable program is achieved. The initial solution may be expressed in English or some form of mathematical notation. Suppose we devise a program for sorting a set of n given by the following 1 distinct integers.

A look ahead to problems which may arise later is often useful. This method of design is called the top-down approach. At this level the formulation is said to be abstract because it contains no details regarding how the objects will be represented and manipulated in a computer. If possible the designer attempts to partition the solution into logical subtasks. We are now ready to give a second refinement of the solution: One solution is to store the values in an array in such a way that the i-th integer is stored in the i-th array position.

One of the simplest solutions is "from those integers which remain unsorted. Underlying all of these strategies is the assumption that a language exists for adequately describing the processing of data at several abstract levels. Let us examine two examples of top-down program development. Experience suggests that the top-down approach should be followed when creating a program. There now remain two clearly defined subtasks: Eventually A n is compared to the current minimum and we are done.

We first note that for any i. We observe at this point that the upper limit of the for-loop in line 1 can be changed to n. A j t The first subtask can be solved by assuming the minimum is A i. From the standpoint of readability we can ask if this program is good. Is there a more concise way of describing this algorithm which will still be as easy to comprehend?

Substituting while statements for the for loops doesn't significantly change anything.. Let us develop another program. By making use of the fact that the set is sorted we conceive of the following efficient method: There are three possibilities. Continue in this way by keeping two pointers. We assume that we have n 1 distinct integers which are already sorted and stored in the array A 1: Below is one complete version. This method is referred to as binary search. Note how at each stage the number of elements in the remaining set is decreased by about one half.

There are many more that we might produce which would be incorrect. In fact there are at least six different binary search programs that can be produced which are all correct. Whichever version we choose.

For instance we could replace the while loop by a repeat-until statement with the same English condition. Part of the freedom comes from the initialization step.

Given a set of instructions which perform a logical operation.. Recursion We have tried to emphasize the need to structure a program to make it easier to achieve the goals of readability and correctness. As we enter this loop and as long as x is not found the following holds: Unfortunately a complete proof takes us beyond our scope but for those who wish to pursue program proving they should consult our references at the end of this chapter.

Actually one of the most useful syntactical features for accomplishing this is the procedure. The procedure name and its parameters file: Of course.. When is recursion an appropriate mechanism for algorithm exposition?

One instance is when the problem itself is recursively defined. For these reasons we introduce recursion here. This view of the procedure implies that it is invoked.

What this fails to stress is the fact that procedures may call themselves direct recursion before they are done or they may call other procedures which again invoke the calling procedure indirect recursion..

Factorial fits this category. These recursive mechanisms are extremely powerful. This is unfortunate because any program that can be written using assignment. Most students of computer science view recursion as a somewhat mystical technique which only is useful for some very special class of problems such as computing factorials or Ackermann's function. Given the input-output specifications of a procedure.. The answer is obtained by printing i a followed by all permutations of b.

Given a set of n 1 elements the problem is to print all possible permutations of this set. Then try to do one or more of the exercises at the end of this chapter which ask for recursive procedures.

It is easy to see that given n elements there are n! A is a character string e. A simple algorithm can be achieved by looking at the case of four elements a. B file: It implies that we can solve the problem for a set with n elements if we had an algorithm which worked on n. This may sound strange. But for now we will content ourselves with examining some simple. This gives us the following set of three procedures.

To rewrite it recursively the first thing we do is to remove the for loops and express the algorithm using assignment. The main purpose is to make one more familiar with the execution of a recursive procedure. Suppose we start with the sorting algorithm presented in this section.

We will see several important examples of such structures.. Another instance when recursion is invaluable is when we want to describe a backtracking procedure. Every place where a ''go to label'' appears. The effect of increasing k by one and restarting the procedure has essentially the same effect as the for loop.

Now let us trace the action of these procedures as they sort a set of five integers When a procedure is invoked an implicit branch to its beginning is made. These two procedures use eleven lines while the original iterative version was expressed in nine lines. Notice how in MAXL2 the fourth parameter k is being changed. Procedure MAXL2 is also directly reculsive. Thus a recursive call of a file: There are other criteria for judging programs which have a more direct relationship to performance.

In section 4. The above criteria are all vitally important when it comes to writing software.. Also in that section are several recursive procedures.

The first is the amount of time a single execution will take. The parameter mechanism of the procedure is a form of assignment. These have to do with computing time and storage requirements of the algorithms. The product of these numbers will be the total time taken by this statement. Performance evaluation can be loosely divided into 2 major phases: The second statistic is called the frequency count. Hopefully this more subtle approach will gradually infect your own program writing habits so that you will automatically strive to achieve these goals.

Both of these are equally important. Though we will not be discussing how to reach these goals. There are many criteria upon which we can judge a program. First consider a priori estimation. We would like to determine two numbers for this statement. Rules are also given there for eliminating recursion. It is impossible to determine exactly how much time it takes to execute any command unless we have the following information: Parallelism will not be considered. In both cases the exact times we would determine would not apply to many machines or to any machine.

Neither of these alternatives seems attractive. All these considerations lead us to limit our goals for an a priori analysis.

Consider the three examples of Figure 1. The anomalies of machine configuration and language will be lumped together when we do our experimental studies. Another approach would be to define a hypothetical machine with imaginary execution times. One of the hardest tasks in estimating frequency counts is to choose adequate samples of data. It is possible to determine these figures by choosing a real machine and an existing compiler.

The program on the following page takes any non-negative integer n and prints the value Fn. In the program segment of figure 1. Each new term is obtained by taking the sum of the two previous terms. In our analysis of execution we will be concerned chiefly with determining the order of magnitude of an algorithm. Now 1. In general To clarify some of these ideas..

This means determining those statements which may have the greatest frequency count. In program b the same statement will be executed n times and in program c n2 times assuming n 1.

Then its frequency count is one. The Fibonacci sequence starts as 0. To determine the order of magnitude.. Three simple programs for frequency counting.. A complete set would include four cases: Below is a table which summarizes the frequency counts for the first three cases. Though 2 to n is only n. None of them exercises the program very much.

Step Frequency Step Frequency 2 3 4 5 6 7 1 1 1 0 1 0 1 9 10 11 12 13 14 15 2 n n-1 n-1 n-1 n-1 1 file: We can summarize all of this with a table. At this point the for loop will actually be entered.

Steps 1. These may have different execution counts. Both commands in step 9 are executed once. The for statement is really a combination of several statements. O n is called linear. Execution Count for Computing Fn Each statement is counted once. This notation means that the order of magnitude is proportional to n. We will often write this as O n.

For example n might be the number of inputs or the number of outputs or their sum or the magnitude of one of them. O n2 is called quadratic. O n log n is better than O n2 but not as good as O n. The reason for this is that as n increases the time for the second algorithm will get far worse than the time for the first. O n3 is called cubic.

We write O 1 to mean a computing time which is a constant. These seven computing times. If an algorithm takes time O log n it is faster. For example. O log n. When we say that the computing time of an algorithm is O g n we mean that its execution takes no more than a constant times g n. If we have two algorithms which perform the same task. Often one can trade space for time. An algorithm which is exponential will work only for very small inputs.

Another valid performance measure of an algorithm is the space it requires. Using big-oh notation. On the other hand. For exponential algorithms. Notice how the times O n and O n log n grow much more slowly than the others. We will see cases of this in subsequent chapters. Given an algorithm. For small data sets. Then a performance profile can be gathered using real time calculation. In practice these constants depend on many factors.. This shows why we choose the algorithm with the smaller order of magnitude.

For large data sets. Figures When n is odd H. Coxeter has given a simple rule for generating a magic square: A magic square is an n x n matrix of the integers 1 to n2 such that the sum of every row.

It emphasizes that the variables are thought of as pairs and are changed as a unit. The statement i. The file: Academic Press. Fundamental Algorithms. Thus each statement within the while loop will be executed no more than n2. Special Issue: Since there are n2 positions in which the algorithm must place a number. For a discussion of tools and procedures for developing very large software systems see Practical Strategies for Developing Large Software Systems.

For a discussion of the more abstract formulation of data structures see "Toward an understanding of data structures" by J. ACM Computing Surveys. Kernighan and P. The while loop is governed by the variable key which is an integer variable initialized to 2 and increased by one each time through the loop. For a discussion of good programming techniques see Structured Programming by O. The Elements of Programming Style by B.

For this application it is convenient to number the rows and columns from zero to n. The magic square is represented using a two dimensional array having n rows and n column.

For a further discussion of program proving see file: Can you think of a clever meaning for S. Describe the flowchart in figure 1. American Mathematical Society. Can you do this without using the go to? Now make it into an algorithm. Both do not satisfy one of the five criteria of an algorithm.

Look up the word algorithm or its older form algorism in the dictionary.? Concentrate on the letter K first. How would you handle people with the same last name. Discuss how you would actually represent the list of name and telephone number pairs in a real machine.

Which criteria do they violate? Consider the two statements: For instance.. What is the computing time of your method? Strings x and y remain unchanged. Determine when the second becomes larger than the first. String x is unchanged. The rule is: If x occurs Given n boolean variables x Try writing this without using the go to statement. Implement these procedures using the array facility. Determine how many times each statement is executed.

List as many rules of style in programming that you can think of that you would be willing to follow yourself. Represent your answer in the array ANS 1: NOT X:: Take any version of binary search. Prove by induction: Using the notation introduced at the end of section 1. Trace the action of the procedure below on the elements 2.

CHRISTIE from Iowa
Browse my other articles. I have always been a very creative person and find it relaxing to indulge in basque pelota. I do like exploring ePub and PDF books excitedly .