Data Structures Using C++ VARSHA H. PATIL Head Computer Science and IT Engineering Department Matoshri College of Engineering and Research Centre Nashik 1 3 Oxford University Press is a department of the University of Oxford. It furthers the University’s objective of excellence in research, scholarship, and education by publishing worldwide. Oxford is a registered trade mark of Oxford University Press in the UK and in certain other countries. Published in India by Oxford University Press YMCA Library Building, 1 Jai Singh Road, New Delhi 110001, India © Oxford University Press 2012 The moral rights of the author/s have been asserted. First published in 2012 All rights reserved. No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in any form or by any means, without the prior permission in writing of Oxford University Press, or as expressly permitted by law, by licence, or under terms agreed with the appropriate reprographics rights organization. Enquiries concerning reproduction outside the scope of the above should be sent to the Rights Department, Oxford University Press, at the address above. You must not circulate this work in any other form and you must impose this same condition on any acquirer. ISBN-13: 978-0-19-806623-1 ISBN-10: 0-19-806623-6 Typeset in Times New Roman by Laserwords, Chennai Printed in India by Adage Printers (P) Ltd., Noida 201301 U.P. DSUC c04 V3 October 27, 2011 2:20 PM Page 152 152 DATA STRUCTURES USING C++ Let us consider an example of computing the factorial of a number. Factorial is a mathematical term. The factorial of a number, say n, is equal to the product of all the integers from 1 to n. The factorial of n is denoted as n! = 1 ¥ 2 ¥ 3 ¥ º ¥ n or n! = n ¥ n - 1 ¥ º ¥ 1 (4.1) 4 For example, 10! = 1 ¥ 2 ¥ 3 ¥ 4 ¥ 5 ¥ 6 ¥ 7 ¥ 8 ¥ 9 ¥ 10. The sim plest program to RECURSION calcula te the f actorial of a number is by using a loop with a product variable. Algorithm 4.1 states the iterative process of computing the factorial of n. ALGORITHM 4.1 FEATAn UiteRratiEveS ve rsOionF of Tan HalgEori tBhm Oto OcompKute the factorial of a number 1. start 2. Let n be the number w hose factorial is to be computed and let Factorial = 1 Objectives OBJECTIVES 3. while(n > 1) do Each chapter begins with a list begin After completi ng this chapter, the reader will be able to understand the following: of topics that the readers can • The power of recursion and its workin g Factorial = Factorial * n expect to learn from that • Identi cation of the base case and the gen e r anl c a=s en o f –a r1ecursively de ned problem • Comparison of iterative and recursive s o luetniodns chapter. • The steps to write, implement, test, an4d. desbtuogp recursive functions • The method of implementing recursion using stacks The iterative process of computing the factorial of n in Algorithm 4.1 can also be written as in Algorithm 4.2. Functions are the most basic and useful feature of any programming language. A set of instructions that performs logical operations, which could be very complex and Algorithms ALGORITHM 4.2 numerous in number, can be grouped together as fDunScUtiCo n s c(0a4ls o Vc3a l l eOdc ptorobceerd 2u7r,e 2s)0.1 1 2:20 PM Page 153 AFulln ccthioanps tmearys ccalol nthteaminse lpvleesn otry o ther Afnun cittioenrsa, tanidv eth ev cearlsleido fnu noctfio ntsh ien taulrng omraiyt hm to compute the factorial of a ocafl la tlhgeo craitllhinmg sfu ntcot iosnu. pTphoisr ptr ocess isn ucamlbleedr r ecursion and such functions are called t rheceu rtshivee ofurnecttiiconasl. cAo rneccuerspivtes .fu nction1 m. aksetsa trhte program compact and readable. This Echaacphte ra clogvoerrsit thhem im ispo drteanpt iacstpeedct s of r2ec.u r Lseiotn .n be the number whose factorial is to be computed and let Factorial = 1 in a step-wise manner 3. for I = 1 to n do RECURSION 153 4.1 INTRODalUoCnTgI OwNith a description begin DSUC c04 V3 October 27, 2011 2:20 PM Page 165 oGTfo hiotidss p rfrueocngurcartmsioimvnei n adgen pfidr an cittiicoens eomf pfahcastoizre i a thl eh wa s ri Fttiwancgot osoftr epiproasgl, r aa=sm fsFo tahllcaottw oarrse:i raelad a*b lIe, easy stoig unnidfi ecrastnancde, .a nd error free. Function s a reen tdhe most useful feature that accomplish th1i.s . IAf nfu =nc 1ti,o nth ies nc aflalecdt oursiianlg oaf f unn =ct i1o4n. n asmteo apnd its parameters through instructions. G2i.v eOn tthheer iwnpisuet–, ofuatcptuotr isaple coiffi nca =tio nn ¥o ff aac ftuonrciatilo no,f t(hne -ca 1ll)er simply makes a call to RECURSION 165 it . This v iew of the f unct ion implies thAaltg iot riisth imnvso 4k.e1d ,a nedx e4c.u2t eadr,e aitnedr arteivtuer naelgdo (rwithitmh s for computing the factorial of n. It is pos- oPr rwoigthraomut rCeosudlets )4 .t1o dtheem polancset rwatheesr et shiiteb lwreea tcso u cgrasilvilveed ea I cinrno eA cdtluhgeore sr fiicotvhareml l A di4nel.g4gfi, onfautri titnihtochetn mic oafln ol4e.r r. W 1ffau.chncteotniro inaa, la t coaoll. iTs mhea dme taot hHeTomwaetri cwailth f udinsckti =o n5, dseofiu rnceed = i nA , function calls itself, either directly or Einqd. i(r4ec.1tl)y f, oirt fidase csstaotir d=ia Btlo ,o afbn edn smcpaaankr iaenl =gso C a b. ree dcuefir sniveed recursively as call. Recursive functions help make the program compact and readable. Recursion is Program Codes eRxetcreuPmrRsOeivlGyeR ppAorMowg eCrraOfmuDlsE a a4sr ei.t 1 uesneadb liens at hvea rpireotyg roafm ampperli ctoa teiAHoxTLnpGosrOwe reRsasrInT (cHgdoMiinms g4kp .,fl4er oxsm onpu! rc ro=acc leenc,su s¥leda s(etn isen ta-g,s 1 itlhs)ye!p., a wreh)N erue m1!e =r o1 us program codes in(4 .2) factoirniatl oFf aa cntuomrbiera tlo( pilnayti ngn )complex games againisft hduimska n= i=n t0e,ll itgheennc e. C++ provide implementation { move disk from source to destof the concepts. Comments are else if(n == 1) // end condition provided wherever necessary HTower(disk - 1, source, spare, dest) // Step 1 return 1; move disk from source to dest thu s mak ing th/e/ cSotedpe 2 else HTower(disk - 1, spare, dest, sseolufr-ecex)p la natory and e//a sSyt etpo 3 end if return Factorial(n - 1) * n; understand. } Note that the pseudocode adds a base case when disk = 0, that is, the smallest disk. In this case, we do not need to worry about smaller disks, so we can just move the disk directly. In the other cases, we follow the three-step recursive function already described for disk 5. The Factorial() function is an example Tohfe tare er erecpurersseinvteat iofnu nofc rteicounrs. ivIen c atlhlse i s ssheocwonn idn Fig. 4.6. return statement, the function calls itse lf. The important thing to remember when creat- Flowcharts ing a recursive function is to give an e nd condition. In Program CoHdTeo w4e .r1(3, , tAh, eB , rCe)cursion Flowcharts are provided stops when n becomes 1. In each call of the function, the value of n keeps decreasing. wherever required. They However, when the value reaches 1, the functioHnT oewnedr(s2,. AO, Cn, Bt)he other hand, this functionH Tower(2, C, B, A) provide readers with will run infi nitely if the initial value of n is less than 1, which means that the function is a step-wise and clear not perfect. Therefore, the condition nH To=w e1r(1 s, hA,o Bu, lCd) be chaHnTgoweedr (1to, B n, C , A ) 1. L etH uTsow reer(w1, rCit, eA , B) HTower(1, A, B, C) representation of ≤ the Factorial() function as in Program Code 4.2. algorithms and concepts. (0, A, C, B) (0, C, B, A) (0, B, A, C) (0, A, C, B) (0, C, B, A) (0, B, A, C) (0, A, C, B) (0, C, B, A) Fig. 4.6 Tower of Hanoi—Call tree for three disks PROGRAM CODE 4.2 int Factorial(int n) The root represents the fi rst call to the function. The function cal l is represented as a node in the tree. The child nodes of the node n represent the function calls made by n. For { example, HTower(2, A, C, B) and HTower(2, C, B, A) are the child nodes of HTower(3, if(n <= 1) // end conditiAo,n B, C ) since these are the two function calls that HTower(3, A, B, C ) makes. The leaf return 1; nodes represent the base cases. els e 4.6.3 Checking for Correctness return Factorial(n - 1) * n; One of the most diffi cult aspects of programming recursively is the process of } accepting that the recursive call will do the right thing. The following checklist pro- vides the fi ve conditions that must hold true for recursion to work. If each of these Program Code 4.2 takes advantage of the fact that the factorial of any integer n can be defi ned recursively as the product of n and the factorial of n − 1. For example, 5! = 5 ¥ 4! DSUC c04 V6 December 15, 2011 11:53 AM Page 160 160 DATA STRUCTURES USING C++ We can break this into three basic steps. 1. Move the disk 4 and the ones smaller than that from the peg A (source) to peg C (spare), using peg B (dest) as a spare. We achieve it by recursively using the same function. After fi nishing this, we will have all the disks smaller than disk 4 on peg C (Fig. 4.3). A B C Fig. 4.3 Tower of Hanoi—step 1 2. Now, with all the smaller disks on the spare peg C, we can move disk 5 from peg A to DSUC c04 V3 October 27, 2011 2:20 PM Page 168 peg B (Fig. 4.4). 168 DATA STRUCTURES USING C++ (e) If this is a function, insert instructions to evaluate the expression immediately following return() and store the result on the top of the stack. (f) Use the index of the label of the return address to execute a branch to that label. A B C If all these rules are followed carefully, one can convert recursion to an iterative code. C++ supports recursion and it is handled using a run-time stack. For each function Fig. 4.4 Tower of Hanoi—step 2 call, all the actual parameters are pushed onto the stack. This is also called as activation record. This activation record contains memory for the return value—a pointer to the base 3. Finally, we want disk 4 and the smaller disks to be moved from peg C to peg B. of the previous stack frame in the stack. It includes the return address, that is, the address We do this recursively using the same function again. At the end, we have disk 5 and FEATURES OF THE BOOK ix of the instruction to be executed after the function call is completed. It also includes the smaller ones on peg B (Fig. 4.5). memory for all the parameters and for all the local variables of the function. The working of recursion is as described eaIrlllieur.strations More than 400 well-labelled illustrations 4.9 APPLICATIONS OF RECURSION are provided to aid in clearer The following are the major aruenasd wehresrtea thned pinrogc eossf otfh reec ucrosinonc ecapnt sbe. applied: 1. Artifi cial intelligence 2. Search techniques 3. Game playing A B 4. ComputatiConal linguistics and natural language processing 5. Expert systems Fig. 4.5 Tower of Hanoi—6 n. aPl asttteerpn recognition and computer vision 7. Robotics Recapitulation RECAPITULATION A summary of key topics at • A function may call itself or other functions, and the called functions in turn may the end of each chapter helps again call the calling function. Such functions are called recursive functions. the readers revise all the • Any correct iterative code can be converted into its equivalent recursive code and important concepts explained in vice versa. DSUC c04 V3 October 27, 2011 2:20 PM Page 169 that chapter. It is provided in • The basic concepts and ideas involved with recursion are simple—a function that has to be solved is treated as a big problem and it solves itself by using itself point-wise form for a quick grasp to solve a slightly smaller problem. The recurrence relation is easily converted to of the concepts learnt. recursive code. • The working of recursion is fairly straightforward. However, to understand the RECURSION 169 working of recursion better and to be able to use it well, one requires practice. The best way to obtain this is to write a lot of recursive functions. Key Terms • Recursion can beK uEsYed TfoErR dMividSe and conquer-based search and sort algorithms to DSUC c04 V3 October 27, 2011 2:20 PM Page 172 DSUC c04 V3 iOncctroebaesr e2 7t,h 2e0 1e1f 2 c:2ie0n PcMy o Pf atghee 1s7e0 operaAtiolln sc.hapters provide the reader Binary recursion A simple unary recursive function calls itself once, whereas the binary • For most problems such as the Towewr iotfh H raenoqi,u riescituers iroen vpirseisoenn tso fa nk einyc rteedirbmly s recursive function calls itself twice. A factorial is a unary function, whereas Fibonacci is a elegant solution that is easy to code and simple to understand. binary recursion. along with their Depth of recursion The number of times a function calls itself is known as the recursive defi nitions. 172 DATA STRUCTdUeRpEthS oUfS ItNhGa tC f+u+nction. 170 DATA STRUCTURES USING C++ Direct and indirect recursion When a recursive function calls itself directly, it is called 10.d iTrehcet froeclluorwsiionng acnodd ew ihse ann t hexe afmunpcleti oonf _ca_l_ls_ _a_n ortehceurr sfiuonnc.tion, which in turn calls the fi rst fufnuctnioAn(,) it is called an indirect recursion. EXERCISES End {condition Recursive functions usually have and in fact should have a condition that Muwl otu il dp t lee rm .iCnahte othiec reec uQrsivuee casllts.i oThniss terminating coMnduilttioipnl eis cchaolliecde eqnude csotniodintison. In . Muthlt ei pfu len c tc io hn. ofaiccteor iaql,u wehsetni on n= s1 tpheu ftu ntcoti otne resttu rns 1. I1f. thIinsfi c nointed irteiocnu rwsieorne oncoctu prrse wsehnet,n thet hr e e fu an dc tefiournns wA' (ot)uh;lde koerepe ctaicllainlg kitnseolfw wliethd thgee v alues 3, 2, 1,( 0a), -a1 ,b -as2e, acnadse s ois oonm tiitltle idnfi n- ity . S u c h r ec.ursion is known as endless recursion. (b) a base case is never reached tLhiante air s a ng da ti nr.eee dre caufrtseiorn reDaedpeinndgin g on the way the recur(sci)o nb gortohw (as), aitn ids (cbl)assifi ed as . thel incehara opr ttreeer.. AA rnecsuwrsiever fsu ntcoti otnh ise ssaeid to be linearly recu(rdsi)v en wonhee no fn toh ep eanbdoivneg opera- fun A(); quetisont iionvnoslv eas raeno tpherro revciduresidve acatl l.t Ihf eth eeren isd a nother re c2u.r siFvieb coanlal cinci t fhuen scetti oonf oFpibe(rnat)i o=n Fs ib(n - 1) + Fib(n - 2) is an example of } to be completed after the recursion is over, then it is cal led a( tar)e ed riereccutr srieocnu.r Fsiaocntorial is an o f ev(ae) rlyin ecahrapter. example of linear recursion and Fibonacci is an example of t(rbe)e rtereceu rrseicounr.sion (b) tree Recurrence relation A recurrence is a well-defi ned math ema(tcic)a ll ifnuenacrt iroenc uwrsriitotnen in terms (c) both (a) and (b) of itself; it is a mathematical function defi ned recursivel y suc(dh) a sb no!th = ( na) × a n(nd -(b 1))! (d) none of these Recursive functions A function may call itself or call o th3e.r fAunnyct rioecnus rasnivde tfhuen ccatilolend c faunn bc-e converted into an all equivalent non-recursive function Revtiioenws qinu etusrtnio angsain may call the calling function. Su ch fu(an)c tiaolwnsa yasre called recursive Review Questions functions. (b) never 1. Write a recursive algorithm to check whether a specifi ed character is in a string. Numerous review questions at Stack overfl ow in recursion Each time a function calls it self, (ict )s tosroems eotnime oers more variables 2.o nW trhitee sat arcekc.u rSsiinvcee a ltghoe rsitthamck toh oclodus nat alilml oitcecdu rarmenocuenst oo ff a m sp(edme)c oifiir fye ,td hf ecu hnfuacrntiacoctntieosr n w iinis t ahta siatl r rhineicgguh.r sive the end of every chapter test the 3.r eWcurristeiv ea dreecputhrs mivaey a clgraosrhit hbmec atuhsaet roefm thoev enso na-lal voacilcaubrirle itn4yc. eosWf mohfei cmah o soprfye .tc hSiefiu efcodhl lcaoh wsaiirtnuagcat taeiolrgn io nirs i tah m strraeteagidese rressu'l tcs oinn acn einphteureantll yk rnecouwrsilveed cgodee ? knstorwinng .as stack overfl ow. (a) Greedy paradigm T4a.i l Wrerciuter sai orenc urAsi vree caulgrsoirvieth fmun tchtaiot nfi nisd ss aaildl otoc cbuer rteanilc reesc oufr sai v(sebu )bi fs Dttrhiivenrigde eian ar ean dsn tocr ionpngeqn.udeirn gp aorpa-digm as well as help them think 5.e rWatrioitnes a t ore cbuer psievrefo arlmgoerdi tohnm r tehtuatr nc hfaronmge sa arnec iunrtseigveer ctao l la; boitn(hcae)rr ywD nisyuenm aitbm eisirc .c paallreadd iag mnon-tail outside the box. 6.r eIcnu brsiinoanr.y T sheea fraccht,o trhiael fguivnecnti okne iys aisn ceoxmampaprlee do fw niothn -ttha iel rmeci(duddr)sl ieoB neo,lt ewhm h(eaen)r eta anosdf b (aicnn)a rayrr saeya. rIcfh a ism aant cehx aomcpculer so, ft thaei l sreeacrucrhs iiosn s.uccessful; else the comp a5r.i soTnh ed aedcivdaenst awgeh eotfh erer ctuhres isoena risc hth at the Winwdionugl da bned r eusntrwicinteddi ntog eoitfh reerc tuhres uiopnp er Ahalllf roerc tuhres ilvoew feu r nhcatli(foa on)f s tchgoeod aetr hsrraiozyeu. gWish r liettwses oa rdeicsutirnscivt e pfhuanscetsi.o Tn hBei nfi arrsyt( kpehya,s Ae,, wn)i,n wdihnegr,e onc icsu trhse w sihzeen o tfh teh ef ua nrrcatyio (Anb) . ist icmaell icnogm iptsleexlfit ya nids lpeusssh- 7.i nWg rvitael uae rse counrtsoiv teh feu nstcatciokn. Tinh Ce +s+e ctoon cdo upnhta tshee, nuunmwbinedr ionfg o, c(occc)u crurseprnsa ccwees hc oeofnm atp hgleeiv xfeiutnyn i cinstti eolgense sri si n paonp pairnragy v. aTlhuee sf ufnroctmio nth seh sotualcdk h, auvseu athllrye ea fptaerra tmhee teenrsd— c oann dair(trdiao)y n,n. tohnee n oufm tbheer a obfo evleements in the array, and the count. 6. The data structure used for recursion is 8. Write a recursive function in C++ that counts the num ber( ao)f osctaccukrrences of a particular digit in the decimal representation of a given integer. F or ex(abm) pqluee, uife the parameters to the function are 8 and 382885, the function should return 3 as( cth) ertere aere three occurrences of the digit 8 in 382885. (d) none of the above [Hint: Remember that n % 10 will give th e remainde r 7o. f Cn odnivsiiddeerd tbhye f1o0l,l owwhinerge caos dne/:10 will give the inte ger part of n divided by 10.] void foo(int n, int sum 0) 9. Write a recursive function in C++ to replace every occur rence of a specifi ed character in { a string with another character. The function should be a void function and should have int k = 0, j = 0; three parameters—a string, a character to be replaced, and the character with which it is if(n == 0) return; to be replaced. k = n % 10; j = n/10; 10. Write a recursive function in C++ to compute the square root of a number. sum = sum + k; 11. Write a recursive function in C++ to convert decimal integers to their radix r representation foo(j, sum); by successive divisions. Dedicated to My parents, Ashatai and Motianna Gunjal and My in-laws, Sumantai and Kashiram Patil Preface The study of data structures serves as the foundation for several fields of computer science such as programming, compiler design, and database management. Almost every program or software uses data structures as an effective and efficient means of data storage and organization. Often, the success of a program or software depends upon the way the data is represented and the algorithm used to process the data. While programming, different kinds of data are required to be stored and processed in the computer. Data can be stored in a generalized format using variables. A data structure uses a collection of related variables that can be accessed individually or as a whole, and represents a set of data items with a specific relationship amongst them. Thus, choosing an effective data structure is the key to success in the design of algorithms. For designing an effective algorithm, a programmer can choose the most efficient data structure from a variety of available ones. Some common data structures include arrays, linked lists, hash tables, heaps, trees, tries, stacks, and queues. Different kinds of data structures are suited for different kinds of ap- plications. For example, arrays are popularly used in searching, sorting, and matrix-related operations. Stacks, on the other hand, are used for converting infix=expressions to postfix and prefix forms, revers- ing a string, processing function calls, parsing computer programs, and simulating recursion. Similarly, queues are most useful in simulating complex real-world problems. The data structures course has found its way into the undergraduate curriculum due to rapid devel- opment and advances in the field of computer science. This course is taught using different program- ming languages such as C, C++, and Java. We shall learn this course using C++, as it has emerged as one of the leading object-oriented programming languages, and is used extensively in both academia and industry. about the book Data Structures Using C++ is designed to serve as a textbook for undergraduate courses in computer science and engineering and postgraduate courses in computer applications. This book seeks to incul- cate a scientific aptitude in the readers by laying special emphasis on the understanding of the concepts with the help of simple language and user-friendly presentation. It also intends to develop independent thinking by focussing on real-world examples as well as the practical aspects of this course through numerous chapter-end exercises. The book emphasizes the following aspects of studying a course on data structures: • the skills required in defining the level of abstraction of data structures and algorithms; • the ability to devise alternate implementations of a data structure; and • the implementation of all the characteristics of data structures through C++. While developing the content for this book the aim has been to make the readers understand the use of abstract data types (ADTs), classes, and various techniques for building simple data structures. Preface v key features • Each concept in this book is explained by an algorithm and a piece of program code implemented through C++, for imparting practical knowledge to the readers. • Numerous illustrations, diagrams, and flowcharts are included to aid the understanding of concepts. • A glossary is provided at the end of every chapter, which helps the readers assimilate the key concepts efficiently. • A summary is given at the end of every chapter for a quick recapitulation of all the important topics discussed. • Extensive chapter-end exercises consisting of solved multiple choice questions, review questions, and programming exercises are included to facilitate revision. organization of the book The book is organized into 15 chapters. Chapter 1 gives an introduction to programming, data structures, and related concepts. This chap- ter covers the various types of data structures, structured programming, and development of software through the software engineering approach. Chapter 2 acquaints the reader with the concept of arrays, which is the most popular and easy-to-use static data structure. Arrays are found in almost every high-level programming language as a built-in data structure. This chapter describes arrays with respect to applications such as polynomials, strings, and sparse matrices. Chapter 3 covers the stack and its implementation as a static data structure. Applications of stacks, such as recursion and infix expression conversion, are discussed. Chapter 4 covers recursion and related concepts. This chapter helps us understand, evaluate, and implement recursive functions. It also elaborates on how recursion works. Chapter 5 illustrates the concept, realization, variations, and applications of queues. A queue is a special type of data structure that performs insertions at one end called the ‘rear’ and deletions at another end called the ‘front’. Chapter 6 covers the basic concepts and realization of the linked list. This dynamic data structure is a powerful tool and is described with respect to applications such as polynomials, strings, and sorting. Chapter 7 deals with trees. A non-linear data structure, the tree is a means to maintain and manipulate data in many applications. Non-linear data structures are capable of expressing more complex relationships than linear data structures. Variations, implementation, and applications of trees are covered in this chapter. Chapter 8 introduces the graph, its representation, traversal techniques, and algorithms used to pro- cess it. In many areas of application such as cartography, sociology, chemistry, geography, mathematics, electrical engineering, and computer science, we often need a representation that reflects arbitrary rela- tionships among the objects. One of the most powerful and natural solutions that models such relation- ships is the graph. vi Preface Chapter 9 explains the basic search and sort techniques that help make the search process more efficient. If the data is kept in proper order, it is much easier to search. Sorting is a process of orga- nizing data in a certain order to help retrieve it more efficiently. Chapter 10 discusses two variations of binary search trees (BSTs)—Adelson-Velskii–Landis (AVL) and optimal binary search trees (OBSTs). A BST is a data structure that has efficient searching as well as insertion and deletion algorithms. Chapter 11 deals with hashing, hash functions, and related aspects. The concepts of searching tech- niques and search trees have already been discussed in Chapters 9 and 10, respectively. In an ideal situa- tion, we expect the target to be searched and identified in one attempt or a minimum number of attempts. One way to achieve this is to know (or to be able to obtain) the address of the record where it is stored. Hashing is a method of directly computing the address of the record with the help of a key, by using a suitable mathematical function called the hash function. Chapter 12 provides an overview of heaps. As discussed earlier, a BST is used for searching and an array is used for sorting data of fixed size that is already collected. On the other hand, when data must be si- multaneously inserted and sorted, then the data structure that works more efficiently than BSTs is the heap. Chapter 13 discusses multiway search trees. Binary search trees generalize directly to multiway search trees. A multiway search tree is a tree of order m, where each node has at most m children. Here m is an integer. If k £ m is the number of children, then the node contains exactly k - 1 keys, which parti- tion all the keys in the subtrees into k subsets. If some of these subsets are empty, then the corresponding children in the tree are also empty. Chapter 14 introduces files and organization. Files contain records that are a collection of informa- tion arranged in a specific manner. File organization refers mainly to the logical arrangement of data in a file system. Chapter 15 briefly covers the standard template library (STL) and its usage. C++ classes provide information for creating libraries of data structures. The C++ class allows for implementation of ADTs, with appropriate hiding of the implementation details. The STL is a part of the standard C++ class li- brary, and can be used as the standard approach for storing and processing data. Chapter 16 introduces the readers to the study of algorithmic strategies and their analyses. Asymptot- ic notations are required to quantify the performance of a particular algorithm. The various algorithmic strategies, namely, divide-and-conquer, greedy method, dynamic programming, and pattern matching required to solve a particular problem effectively and efficiently are discussed in detail. A data structure that represents a set of strings, called tries, is discussed towards the end. It aids in pattern matching by making the process faster. The appendix provides a thorough overview of the fundamentals of C++ programming. C++ has proven to be the most suitable language for the implementation of abstract data types because of the introduction of the concept of classes. I sincerely hope that the readers will be able to make the most out of this book and apply the concepts learnt in their academic and professional tenures. If you have any comments or suggestions that can be incorporated in the future editions of this book, feel free to contact me at [email protected]. Varsha H. Patil ACKNOWLEDGEMENTS Iw ould like to thank many people who encouraged and helped me in various ways throughout this project, namely, my family, my didi Megha and Arvindji jaji, my colleagues, friends, and students. First and foremost I would like to acknowledge Dr Gajanan Kharate, Dr Shirish Sane, Vaishali Pawar, Vaishali Tidke, Seema Gondhalekar, Swati Bhavsar, Alpana Borse, Snehal Umare, and all my col- leagues. Special thanks to Mr Mahesh Sanghvi for his untiring efforts in making this project successful. This book would not have been what it is, without him. I received constant support and motivation from honourable Balasahebwagh, Narendrabhau, Kishorbhau, Laxmanbhau, and Kunal Darabe. I thank them for all the inspiration. My husband, Hemant, encouraged me even before I started writing this book. His contagious en- thusiasm and generous spirit and also the ever-smiling faces of my children Abolee and Saurabh made working on this project a pleasant experience. Finally, I would like to thank my parents, sisters, brother, and all other family members for making the experience of writing this book memorable. Last but not the least, my acknowledgements would remain incomplete if I do not thank the editorial team of Oxford University Press, India, who supported me throughout the development of this manu- script. Dr Varsha H. Patil BRIEF CONTENTS Preface iv Acknowledgements vii Features of the Book viii 1. Fundamental Concepts 1 2. Linear Data Structure Using Arrays 32 3. Stacks 94 4. Recursion 147 5. Queues 168 6. Linked Lists 195 7. Trees 280 8. Graphs 372 9. Searching and Sorting 420 10. Search Trees 479 11. Hashing 527 12. Heaps 556 13. Indexing and Multiway Trees 589 14. Files 638 15. Standard Template Library 677 16. Algorithm Analysis and Design 714 Appendix: Overview of C++ Programming 759 Index 797