Você está na página 1de 185

1

Data Structure Defn:


A data structure is a specialized format for organizing and storing data. General data structure types include the array, the file, the record, the table, the tree, and so on. Data structure is designed to organize data to suit a specific purpose so that it can be accessed and worked with in appropriate ways The logical or mathematical model of a particular organization of data is called a data structure. A carefully chosen data structure will allow the most efficient algorithm to be used. A well-designed data structure allows a ariety of critical operations to be performed, using as few resources, both execution time and memory space, as possible.

Abstract Data Type (ADT)! An ADT is a set of elements with a collection of well defined
operations. The operations can take as operands not only instances of the ADT but other types of operands or instances of other ADTs. "imilarly results need not be instances of the ADT At least one operand or the result is of the ADT type in #uestion.

$%amples of ADTs include list, stack, #ueue, set, tree, graph, etc.

Complexity of Algorithms
&t is ery con enient to classify algorithms based on the relati e amount of time or relati e amount of space they re#uire and specify the growth of time 'space re#uirements as a function of the input size. Thus, we ha e the notions of! Time Complexity! (unning time of the program as a function of the size of input Space Complexity! Amount of computer memory re#uired during the program e%ecution, as a function of the input size.

Algorithm Analysis and Performance Prediction:


Algorithm is a finite se#uence of instructions that the computer follows to sol e a problem. )nce an algorithm for a problem is found to be correct, ne%t step is to find out the resources *time and space+ the algorithm will re#uire. This is known as algorithm analysis. &f your algorithm re#uires more resources than your computer has *such as gigabytes of main memory+, it is useless. Data structures and algorithms are interrelated and should be studied together. ,ecause, the algorithms are the methods used in systematic problem sol ing. -ithout methods for storing data in them, retrie ing data from them and performing computational operations on the data in them data structures are meaningless. Thus, we ha e to study algorithms as well. The computation time and memory space re#uired by data structures and algorithms that operate on them are important.
.

Algorithm Analysis
The finiteness condition implies that an algorithm ne er goes into an infinite loop no matter what input we gi e it. &t is difficult to predict the actual computation time of an algorithm without knowing the intimate details of the computer architecture, the compiler, the #uality of the program and the other factors. ,ut, we can measure the time for a gi en algorithm by using some special performance programs called benchmarks. &t is also possible to predict the performance by looking at the growth rate of an algorithm. &t is known that the running time of the algorithm is a function of the input size such as the number of elements in an array, the number of records in a file etc.. . The amount of time that any algorithm takes to run depends on the amount of input it must process. $%. "orting an array of 1//// elements re#uire more processing time than sorting an array of 1// elements. Another e%ample! it is common to write programs whose running time aries with the s#uare of the problem size. Thus, a program taking 1 sec to complete a file handling problem with 1/ records in the file, re#uire 0 sec for ./ records *not . sec+. &ncreasing the file size by a factor of 1/1 ie 1// records will increase the running time to 1// sec or 1/// records will re#uire 1////sec *2 hours+ to complete33 And 1//// records will re#uire almost two weeks to finish. This is a long time compared to 1 sec for 1/ records test. This e%ample shows that we need to know something about the growth rate of our algorithm as test program running time may grow to unacceptable alues when real-world-sized data is used. An e%perienced programmer estimates the performance of the algorithm and takes some actions if there is any. &n some cases there may be no alternati e solution to the program running in 4s#uared4 time but at least the programmer will not be surprised at the end.

Asymptotic otation
"uppose we are considering two algorithms, A and B, for sol ing a gi en problem. 5urthermore, let us say that we ha e done a careful analysis of the running times of each of the algorithms and determined them to be TA(n)and TB(n), respecti ely, where n is a measure of the problem size. Then it should be a fairly simple matter to compare the two functions TA(n)and TB(n),to determine which algorithm is the best3 &n the general case, we ha e no a priori knowledge of the problem size. 6owe er, if it can be shown that TA(n)7TB(n), say, that for all n0, then algorithm A is better than algorithm B regardless of the problem size. 8nfortunately, we usually don9t know the problem size before hand, nor is it true that one of the functions is less than or e#ual the other o er the entire range of problem sizes. &n this case, we consider the asymptotic beha ior of the two functions for ery large problem siz Definition: Asymptotic notation is used to gi e a rough estimate of the rate of growth of a formula. The formula usually gi es the run time of an algorithm. &nformally, ) notation is the leading *i.e. #uickest growing+ term of a formula with the coefficient stripped. An Asymptotic !pper "ound#"ig $h:

2 &n 1:;., <. ,achmann in ented a notation for characterizing the asymptotic beha ior of functions. 6is in ention has come to be known as big oh notation! Definition ("ig $h) =onsider a function f*n+ which is non-negati e for all integers n0 . -e say that >>f*n+ is big oh g*n+,99 which we write f*n+?O*g*n++, if there e%ists an integer n0 and a constant c / such that for all integers n n0, f(n) !cg(n).

$.g.

n, 1///n and @nA. - )*n+ nAlog n are )*n+ n. AnAlog n, 1/n. An - )*n.+ n log nA1/n - )*n log n+ 1/ log. n - )*log. n+ 1////, .@/ and 0 - )*1+

Computing big#$ of an Algorithm: 5ollowing is a shorter way to compute big-) for an algorithm! Atomic operations- =onstant time =onsecuti e statements- "um of times =onditionals- Barger branch time plus test time Boops- "um of iterations 5unction =alls - Time of function body (ecursi e 5unctions - "ol e (ecurrence (elation

Conventions for Writing Big Oh Expressions


=ertain con entions ha e e ol ed which concern how big oh e%pressions are normally written!

5irst, it is common practice when writing big oh e%pressions to drop all but the most significant terms. Thus, instead of we simply write . , we simply

"econd, it is common practice to drop constant coefficients. Thus, instead of

write . As a special case of this rule, if the function is a constant, instead of, say )*1/.0+, we simply write O*1+. An Asymptotic %o&er "ound#$mega The big oh is an asymptotic upper boun". &n this section, we introduce a similar notation for characterizing the asymptotic beha ior of a function, but in this case it is a lower boun".

0 Definition ($mega) =onsider a function f*n+ which is non-negati e for all integers , if there e%ists an integer . , . -e say and a constant

that >>f*n+ is omega g*n+,99 which we write c / such that for all integers

The definition of omega is almost identical to that of big oh. The only difference is in the comparison-for big oh it is 1 for omega, it is .

'.( )ro&th *ates


The appro%imate computation time is formulatingd it in terms of the problem size C. &f we consider that the system dependent factor *such as the compiler, language, computer+ is constant1 not arying with the problem size we can factor it out from the growth rate. The growth rate is the part of the formula that aries with the problem size. -e use a notation called )-notation *4growth rate4, 4big-)4+. The most common growth rates in data structure are! e%pression name O*1+ constant logarithmic log s#uared O*n+ linear n log n #uadratic cubic e%ponential Table: The names of common big oh e%pressions. &f you calculate these alues you will see that as C grows log*C+ remains #uite small and Clog*C+ grow fairly large but not as large as C . $%. Dost sorting algorithms ha e growth rates of Clog*C+ or C . 5ollowing table shows the growth rates for a gi en C.
. .

'.+ ,stimating the )ro&th *ate


Algorithms are de eloped in a structured way1 they combine simple statements into comple% blocks in four ways! "e#uence, writing one statement below another Decision, if-then or if-then-else Boops "ubprogram call Bet us estimate the big-) of some algorithm structures! #imple statements! -e assume that statement does not contain a function call. &t takes a fi%ed amount to e%ecute. -e denote the performance by )*1+, if we factor out the constant e%ecution time we are left with 1. #e$uence of simple statements! &t takes an amount of e%ecution time e#ual to the sum of e%ecution times of indi idual statements. &f the performance of indi idual statements are )*1+, so is their sum. %ecision! 5or estimating the performance, then and else parts of the algorithm are considered independently. The performance estimate of the decision is taken to be the largest of the two indi idual big )s. 5or the case structure, we take the largest big ) of all the case alternati es. #imple counting loop& This is the type of loop in which the counter is incremented or decrement each time the loop is e%ecuted *for loop+. &f the loop contains simple statements and the number of times the loop e%ecutes is a constant1 in other words, independent of the problem size then the performance of the whole loop is )*1+. )n the other hand if the loop is like ,x: for *i?/1 iE C1 iAA+ the number of trips depends on C1 the input size, so the performance is )*C+. 'este" loops& The performance depends on the counters at each nested loop. 5or e%! ,x: for *i?/1 iE C1 iAA+ F for *G?/1 GE C1 iAA+ F
se#uence of simple statements

I H

the outer loop count is C but the inner loop e%ecutes C times for each time. "o the body of the inner loop will e%ecute CJC and the entire performance will be )*C.+. ,x: for *i?11 iE?C1 iAA+ F for *G?/1 GE i1 GAA+ F
se#uence of simple statments

H
H

&n this case outer count trip is C, but the trip count of the inner loop depends not only C, but the alue of the outer loop counter as well. &f outer counter is 1, the inner loop has a trip count 1 and so on. &f outer counter is C the inner loop trip count is C. 6ow many times the body will be e%ecutedK 1A.A2ALL*C-1+AC ? C*CA1+ ' . ? **C + AC +'. Therefore the performance is )*C.+. 5or large C the contribution of the C'. term is negligible
.

)enerali-ation: A structure with k nested counting loops where the counter is Gust incremented or decrement by one has performance )*Ck+ if the trip counts depends on the problem size only. (hile loops& The control ariable is multiplied or di ided, each time the loop iteration is performed. $ach loop has an initialization step, a termination condition and a modification step indicating how the control ariable should be changed. &n while-structure, the termination condition is checked before the iteration. Bet9s consider the following! control?11 while *control E n+ F
"imple statements1

control?.Jcontrol1 H &n the abo e e%ample performance depends on the problem size C. The control ariable is multiplied by . until it gets larger than C. The initial alue of control is 1, after k iterations we will ha e control ? .k &n order to find k we take the log of both sides1 log . *control+ ? log..k , log. *control+?k . "ince the loop stops when control M C , the performance of the algorithm is )*log. C +.

N )enerali-ation! Assume that we multiply the control by some other constant1 say fact. Then after k iterations1 control ? fact k so, the performance is )*log*C++ where the log is taken to the base fact. &n considering the performance base does not matter as form one base to another the additional factor is a constant. Ouadratic algorithms are impractical for input sizes e%ceeding a few thousand. =ubic algorithms are impractical for input sizes e%ceeding a few hundred.

(...(. )eneral *ules


(8B$ 1-5)( B))<"!

The running time of a for loop is at most the running time of the statements inside the for loop *including tests+times the number of iterations.
(8B$ .-C$"T$D 5)( B))<"!

Analyze these inside out. The total running time of a statement inside a group of nested for loops is the running time of the statement multiplied by the product of the sizes of all the for loops. As an e%ample, the following program fragment is )*n.+!
for( i=0; i<n; i++ ) for( j=0; j<n; j++ ) k++;

(8B$ 2-=)C"$=8T&P$ "TAT$D$CT"!

These Gust add *which means that the ma%imum is the one that counts+. As an e%ample, the following program fragment, which has )*n+ work followed by ) *n.+ work, is also ) *n.+!
for( a[i] for( for( a[i] i=0; i<n; = 0; i=0; i<n; j=0; j<n; += a[j] + i++) i++ ) j++ ) i + j;

(8B$ 0-l5'$B"$!

5or the fragment


if( cond ) S1 else S2

the running time of an if'else statement is ne er more than the running time of the test plus the larger of the running times of "1 and "..

: STAC/ A stack is a linear data structure for collection of items , with the restriction that items can be added one at a time and can only be remo ed in the re erse order in which they were added *i-e %ast 0n 1irst $ut %01$+. The last item represents the top of the stack. "uch a stack resembles a stack of trays in a cafeteria, or stack of bo%es. )nly the top tray can be remo ed from the stack and it is the last one that was added to the stack. A tray can be remo ed only if there are some trays on the stack, and a tray can be added only if there is enough room to hold more trays. The common operations associated with a stack are as follows! 1. push! adds a new item on top of a stack. .. pop! remo es the item on the top of a stack 2. is,mpty! =heck to see if the stack is empty 0. is1ull! =heck to see if stack is already full @. returnTop! &ndicate which item is at the top Applications: A stack is ery useful in situations when data ha e to be stored and then retrie ed in the re erse order. '. 1unction Calls .. con2ert an infix expression into postfix form. e.g. &nfi% aAbJc *aAb+Jc *a A b+ J *c Q d+ <ostfi% abcJA abAcJ abAcd-J

+. ,2aluation of arithmetic expressions


e.g

@ J 2 A. A I J 0 ? @ 2 J . A I 0 J A 0nfix to postfix con2ersion!

? 01

A stack can also be used to con ert an infi% e%pression in standard form into postfi% form. &nfi%! operator is between operands A A , <ostfi% ! operator follows operands A , A -e shall assume that the e%pression is a legal one *i.e. it is possible to e aluate it+. 1. -hen an operand is read, it will be placed on output list *printed out straight away+.

; .. The operators are pushed on a stack. 6owe er, if the priority of the top operator in the stack is higher than the operator being read, then it will be put on output list, and the new operator pushed on to the stack. The priority is assigned as follows. 1. * Beft parenthesis in the e%pression .. J ' 2. A Q 0. * Beft parenthesis inside the stack The association is assumed to be left to right. The left parenthesis has the highest priority when it is read from the e%pression, but once it is on the stack, it assumes the lowest priority. Algorithm: while there are more characters in the input { Read next symbol ch in the given infix expression. If ch is an operand put it on the output. If ch is an operator i.e.* , /, , !, or " { If stac# is empty push ch onto stac#$ %lse chec# the item op at the top of the stac#$ end while "more items in stac# && priority"ch'<( priority"op'' { pop op and append it to the output, provided it is not an open parenthesis op ( top element of stac# ) push ch onto stac# ) If ch is right parenthesis *'+ ,op items from stac# until left parenthesis is reached ,op left parenthesis and discard both left and right parenthesis )/* now no more characters in the infix expression*/ ,op remaining items in the stac# to the output.

1/ Graphical representation! e-g 1

(esulting <ostfi% $%pression ! 3 P / 4 T 5 6 ,.g ( con2ert (5+7((#')685(.#') into Postfix expression

e.g +: a A ** b J c + ' d + a A * * b c J + 'd + *precedence of J and ' are same and they are left associati e+ aA*bcJd'+ abcJd'A

11 ,2aluating a Postfix ,xpression -e can e aluate a postfi% e%pression using a stack. 1. $ach operator in a postfi% string corresponds to the pre ious two operands . .. $ach time we read an operand we push it onto a stack. 2. -hen we reach an operator its associated operands *the top two elements on the stack + are popped out from the stack. 0. -e then perform the indicated operation on them and push the result on top of the stack so that it will be a ailable for use as one of the operands for the ne%t operator .

1. 0mplementation of stac9s using arrays: /* ,rogram of stac# using array*/ -include <./0I1.23 -define 456 78 int top ( !9$ int stac#:arr;456<$ main"' { int choice$ while"9' { switch"choice' { case 9 = push"'$ brea#$ case >= pop"'$ brea#$ case ?= display"'$ brea#$ case @= exit"9'$ default= printf"ABrong choiceCnA'$ )/*%nd of switch*/ )/*%nd of while*/ )/*%nd of main"'*/ push"' { int pushed:item$ if"top ( ( "456!9'' printf"A.tac# 1verflowCnA'$ else { printf"A%nter the item to be pushed in stac# = A'$ scanf"ADdA,&pushed:item'$ top(top 9$ stac#:arr;top< ( pushed:item$ )

12 )/*%nd of push"'*/

pop"' { if"top ( ( !9' printf"A.tac# EnderflowCnA'$ else { printf"A,opped element is = DdCnA,stac#:arr;top<'$ top(top!9$ ) )/*%nd of pop"'*/

display"' { int i$ if"top ( ( !9' printf"A.tac# is emptyCnA'$ else { printf"A.tac# elements =CnA'$ for"i ( top$ i 3(8$ i!!' printf"ADdCnA, stac#:arr;i< '$ ) )/*%nd of display"'*/

/* ,rogram for conversion of infix to postfix and evaluation of postfix. It will ta#e only single digit in expression */ -include <stdio.h3 -define Flan# G G -define /ab GCtG -define 456 78 long int pop "'$ long int eval:post"'$ char infix;456<, postfix;456<$ long int stac#;456<$ int top$

10 main"' { long int value$ top ( 8$ printf"A%nter infix = A'$ gets"infix'$ infix:to:postfix"'$ // calling infix to postfix conversion function printf"A,ostfix = DsCnA,postfix'$ value(eval:post"'$ // caling the function for evaluating the expression printf"AHalue of expression = DldCnA,value'$ printf"ABant to continue"y/n' = A'$ )/*%nd of main"'*/ infix:to:postfix"' { int i,p(8,type,precedence$ char next $ for"i(8$ infix;i<I(+C8+$ i { '

if" Iwhite:space"infix;i<'' { switch"infix;i<' { case G"G= push"infix;i<'$ brea#$ case G'G= while""next ( pop"'' I( G"G ' postfix;p < ( next$ brea#$ case G G= case G!G= case G*G= case G/G= case GDG= case GJG= precedence ( prec"infix;i<'$ while"topI(len && precedence<( prec"stac#;top<'' postfix;p < ( pop"'$ push"infix;i<'$ brea#$ default= postfix;p
/*if an operand comes */

< ( infix;i<$

1@ ) ) )
/*%nd of switch */ /*%nd of if */ /*%nd of for */

while"topI(len' postfix;p < ( pop"'$ postfix;p< ( GC8G $ /*%nd postfix withGC8G to ma#e it a string*/ )
/*%nd of infix:to:postfix"'*/

/* /his function returns the precedence of the operator */ prec"char symbol ' { switch"symbol' { case G"G= return 8$ case G G= case G!G= return 9$ case G*G= case G/G= case GDG= return >$ case GJG= return ?$ ) /*%nd of switch*/ ) /*%nd of prec"'*/ push"long int symbol' { if"top 3 456' { printf"A.tac# overflowCnA'$ exit"9'$ ) else { top(top 9$ stac#;top< ( symbol$ ) ) /*%nd of push"'*/ long int pop"'

1I { if "top (( !9 ' { printf"A.tac# underflow CnA'$ exit">'$ ) else return "stac#;top!!<'$ )


/*%nd of pop"'*/

// function to chec# the symbol is a blan# space or not white:space"char symbol' { if" symbol (( Flan# KK symbol (( /ab KK symbol (( GC8G' return 9$ else return 8$ ) /*%nd of white:space"'*/ // function to evaluate an expression long int eval:post"' { long int a,b,temp,result,len$ int i$ len(strlen"postfix'$ postfix;len<(G-G$ for"i(8$postfix;i<I(G-G$i ' { if"postfix;i<<(GLG && postfix;i<3(G8G' push" postfix;i<!@M '$ else { a(pop"'$ b(pop"'$ switch"postfix;i<' { case G G= temp(b a$ brea#$ case G!G= temp(b!a$

1N brea#$ case G*G= temp(b*a$ brea#$ case G/G= temp(b/a$ brea#$ case GDG= temp(bDa$ brea#$ case GJG= temp(pow"b,a'$ ) push"temp'$
/*%nd of switch */

) /*%nd of else*/ ) /*%nd of for */ result(pop"'$ return result$ )


/*%nd of eval:post */

<rogram to con ert decimal number to binary number /* ,rogram of stac# using array*/ -include <./0I1.23 -define 456 78 int top ( !9$ int stac#:arr;456<$ main"' { int dec$ printf"N enter a decimal numberCnO' scanf"NDdO,&dec'$ while"n38' { rem ( dec/>$ push"rem'$ dec(dec/>$ ) printf"Nbinary number = CnO'$ while"topI(!9' { b(pop"'$ printf"NDdO,b' ) )

1:

1; :ueue A #ueue is simply a waiting line that grows by adding elements to its end and shrinks by remo ing elements from the front. =ompared to stack, it reflects the more commonly used ma%im in real-world, namely, Rfirst come, first ser edS. -aiting lines in supermarkets, banks, food counters are common e%amples of #ueues. Definition: &t is a list from which items may be deleted at one end *front+ and into which items may be inserted at the other end *rear+. &t is also referred to as a first-in-first-out *5&5)+ data structure.

$perations on :ueue: '. en;ueue (;< x) inserts item % at the rear of the #ueue # (. x = de;ueue (;) remo es the front element from # and returns its alue. +. is,mpty(;) =heck to see if the #ueue is empty. .. is1ull(;) checks to see if there is space to insert more items in the #ueue. Oueue o2erflo& results from trying to add an element onto a full #ueue and #ueue underflo& happens when trying to remo e an element from an empty #ueue. Applications of :ueues: Oueues ha e many applications in computer systems! 1. Direct application 6andling Gobs in a single processor computer print spooling transmitting information packets in computer networks .. &ndirect applications Au%iliary data structure for algorithms =omponent of other data structures Program for :ueue implementation through Array: -include <stdio.h3

./ -include<ctype.h3 - define 456.IP% >88 int Q;456.IP%<$ int front(!9$ int rear ( !9$ void enQueue"int'$ int deQueue"'$ void main"' { int choice(9,i,num$ while"choice ((9' { printf"A 45IR 4%RE= 9.5dd element to Queue >.0elete element from the Queue A'$ scanf"ADdA,& choice'$ switch"choice' { case 9= printf"A%nter the data... A'$ scanf"ADdA,&num'$ enQueue"num'$ brea#$ case >= i(deQueue"'$ printf"AdeQueued value is Dd A,i'$ brea#$ default= printf"AInvalid Shoice ... A'$ ) printf"A0o you want to continue press 9 for yes, any other #ey to exitA'$ scanf"ADdA , & choice'$ ) )
//end of outer while //end of main

void enQueue"int a' { if"rear((456.IP%!9' { printf"A TE%E% UEVVA'$ return$

.1 ) else { rear ( rear 9 Q;rear<(a$ printf"A Halue of DdA,rear,front'$ ) ) int deQueue"' { int a$ if"front (( rear' { printf"A TE%E% %4,/WA'$ return"8'$ ) else { front ( front 9 a(Q;front<$ ) return"a'$ )

rear

Dd

and

the

value

of

front

is

..

Circular :ueue
Binear #ueues ha e a ery big drawback that once the #ueue is 58BB, e en though we delete few elements from the 4front4 and relie e some occupied space, we are not able to add anymore elements, as the 4rear4 has already reached the Oueue9s rear most position.

"olution! )nce 4rear4 reaches the Oueue9s ma%imum limit, the 4first4 element will become the #ueue9s new 4rear4. Cow the Oueue is not straight but circular. i-e once the Oueue is full the 45irst4 element of the Oueue becomes the 4(ear4 most element, if and only if the 45ront4 has mo ed forward1

Circular :ueue "oundary Conditions: -hen the #ueue is empty, there is no front item and no rear item ,ut if the front and rear ariables point to alid array items, the difference between an empty #ueue and a non-empty #ueue can be identified by o Dethod 1! set front and'or rear to an out of range alue *such as -1+ to indicate an empty #ueue o Dethod .! use a separate counter or ,oolean flag to indicate an empty #ueue, in which case *rearA1+TDAU ?? front while the #ueue is empty *note that this is also the case when the #ueue is full3+ o Dethod 2! always keep at least one #ueue entry unused. Then an empty #ueue has condition *rearA1+TDAU ?? front , while a full #ueue has condition *rearA.+TDAU ?? front Program for Circular :ueue implementation through Array

.2

-include <stdio.h3 -include<ctype.h3 - define 456.IP% M int cQ;456.IP%<$ int front(!9, rear(!9$ void enQueue"int'$ int deQueue" '$ void main"' { int choice(9,i,num$ clrscr"'$ while"choice ( (9' { printf"A 45IR 4%RE= Cn 9.5dd element to Sircular Tueue Cn >.0elete element from the Sircular Tueue Cn A'$ scanf"ADdA,& choice'$ switch"choice' { case 9= printf"A%nter the data... A'$ scanf"ADdA,&num'$ enQueue"num'$ brea#$ case >= i(deQueue"'$ printf"AHalue returned from deQueue function is brea#$ default= printf"AInvalid Shoice . A'$ )

Dd A,i'$

printf"A 0o you want to do more operations on Sircular Tueue " 9 for yes, any other #ey to exit' A'$ scanf"ADdA , &choice'$ ) ) //end of //end of main outer while

void enQueue"int item'

.0 { rear(rear 9$ rear( "rearD456'$ if"front ( (rear' { printf"ASIRSEV5R TE%E% UEVVA'$ return$ ) else { cQ;rear<(item$ printf"ARear ( Dd Uront ( Dd A,rear,front'$ ) ) int deQueue"' { int a$ if"front ( ( rear' { printf"ASIRSEV5R ./5SX %4,/WA'$ return "8'$ ) else { front(front 9$ front ( frontD456$ a(cQ;front<$ printf"ARear ( Dd Uront ( Dd A,rear,front'$ return"a'$ ) ) Applications: '. *ound robin scheduling &t is one of the oldest, simplest, and most widely used scheduling algorithms, designed especially for time#sharing systems. A small unit of time, called timeslice or ;uantum, is defined. All runnable processes are kept in a circular #ueue. The =<8 scheduler goes around this #ueue, allocating the =<8 to each process for a time inter al of one #uantum. Cew processes are added to the tail of the #ueue. The =<8 scheduler picks the first process from the #ueue, sets a timer to interrupt after one #uantum, and dispatches the process.

.@ &f the process is still running at the end of the #uantum, the =<8 is preempted and the process is added to the tail of the #ueue. &f the process finishes before the end of the #uantum, the process itself releases the =<8 oluntarily. &n either case, the =<8 scheduler assigns the =<8 to the ne%t process in the ready #ueue. $ ery time a process is granted the =<8, a context s&itch occurs, which adds o erhead to the process e%ecution time.

.I LINKED LISTS Bist is a ordered collections of obGects. The lin9ed list is a data structure which consists of a series of structures, which are not necessarily adGacent in memory. $ach structure contains the data and a pointer to a structure containing its successor. -e call this the ne%t pointer. The last cell9s ne%t pointer points to C8BB Arrays &n an array each node *element+ follows the pre ious one physically *i.e. contiguous spaces in the memory+ Arrays are fi%ed size! either too big *unused space + or not big enough *o erflow problem+ Da%imum size of the array must be predicted which is sometimes not possible. &nserting and deleting elements into an array is difficult. 6a e to do lot of data mo ement, if in array of size 1//, an element is to be inserted after the 1/ th lement, then all remaining ;/ ha e to be shifted down by one position. %in9ed %ists Binked lists are appropriate when the number of data elements to be represented in the data structure are not known in ad ance. Binked lists are dynamic, so the length of a list can increase or decrease as necessary. A linked list is a collection of nodes, each node containing a data element. $ach node does not necessarily follow the pre ious one physically in the memory. Codes are scattered at random in memory. &nsertion and Deletion can be made in Binked lists, by Gust changing links of a few nodes, without disturbing the rest of the list. This is the greatest ad antage. ,ut getting to a particular node may take large number of operations. $ ery node from start needs to be tra ersed to reach the particular node. Types: "ingle linked list =ircular linked list Doubly linked list Single lin9ed list : Code structure! A node in a linked list is a structure that has at least two fields. )ne of the fields is a data field1 the other is a pointer that contains the address of the ne%t node in the se#uence. struct node { int data; struct node *next; }

.N The pointer ariable next is called a link. $ach structure is linked to a succeeding structure by way of the field next. The pointer ariable next contains an address of the location in memory of the successor structnode element or the special alue REVV.

%in9ed list &ith actual pointer 2alues

3ore examples of odes: '. A node &ith one data field:

struct node F int number1 struct node J link1 H1 (. A node &ith + data fields:

struct student F char nameV./W1 int id1 double grd<ts1 struct student Jne%tXstudent1 H1 +. A structure in a node:

struct person

.: F char nameV./W1 char addressV2/W1 char phoneV1/W1 H1 struct personXnode F struct person data1 struct personXnode Jne%t1 H1

A simple %in9ed %ist:

Y The head pointer addresses the first node of the list, and each node points at its successor node. Y The last node has a link alue C8BB. ,mpty %ist: $mpty Binked list is a single pointer ha ing the alue of C8BB. p6ead ? C8BB1 "asic %in9ed %ist $perations: 1. Add a node .. Delete a node 2. Booking up a node 0. Bist Tra ersal *e.g. =ounting nodes+ '. Add a ode: There are four steps to add a node to a linked list! 1. Allocate memory for the new node. .. Determine the insertion point *you need to know only the new nodeZs predecessor+ 2. <oint the new node to its successor. 0. <oint the predecessor to the new node. ,.g. adding T&o nodes to an ,mpty %ist: To form linked list which contains two integers 2; and I/, first define a structure to hold two pieces of information in each node- an integer alue, and the address corresponding to the ne%t structure of same type. struct node > int data?

.; struct node 5next? @? struct node 5p e&< 5pAead? 8se malloc to fetch one node from the memory, and let p'ew point to this node. p e& = (struct node 5) malloc(si-eof(struct node))? pAead = !%%? Cow to store 2; in the data part of the node, we can use (5p e&).data = +B? A more con enient way is to use the notation p e&#Cdata = +B? p e&#Cnext = !%%?

At this moment there are no elements in the list. <ointer p6ead points to C8BB. 5irst element 2; is stored in node pCew. "o make it the head node. p e&#Cnext = pAead? 'J set link to C8BBJ' pAead = p e&? 'J point list to first nodeJ'

Cow we ha e got one node in the list, which is being pointed to by p)ea". To put the ne%t alue I/ on the list, we must use malloc to fetch another node from the memory. pRew ( "struct node *' malloc"siYeof"struct node''$ Bet us now assign the data alue to this node! pRew!3data ( Z8$ pRew!3next ( REVV$

Cow we need to link this new node to the p)ea" node, which can be done by following statement! p2ead!3next ( pRew$ This gi es us the list of two nodes!

2/

Add a node at the end of the list: Gi en the list p)ea"

let us say we are interested in adding a node containing ;/ at the end of this list. As a first step, use malloc to get a new node p'ew from the memory and load ;/ in the data field and C8BB in the ne%t field. pRew!3data ( L8$ pRew!3next ( REVV$

Cow, the last node containing :/ would become the predecessor of the node containing ;/ after the node is added. Bet us call this node as p*re. 8se a temporary ariable p*re and initialize it to p)ea". Cow hop through the nodes till you get a node whose ne+t link is C8BB. Then p*re will be pointing to the last node. p,re ( p2ead$ while " p,re!3next I( REVV ' p,re ( p,re!3next$ Cow link p*re with p'ew . p,re!3next ( pRew$ This would result in the node pNew to be attached to the list as the last node.

0nserting a node in a %in9ed %ist: ()eneral case)

21

0nsertion into a lin9ed list

"o far we ha e been discussing separate codes for inserting a node in the middle, at the end or at front of a list. -e can combine all the codes and write a general code for inserting a node anywhere in the list. Gi en the head pointer *p6ead+, the predecessor *p<re+ and the data to be inserted *item+, we first allocate memory for the new node *pCew+ and adGust the link pointers. struct node { int data$ struct node *next$ )$ struct node *p2ead$ p2ead(REVV=

void insert:begin"int val' { struct node *pRew$ pRew ( "struct node *'malloc"siYeof"struct node''$ pRew!3data ( val$ if "p2ead (( REVV' { /*Addin to e!"t# list*/ p2ead ( pRew$ p2ead!3next( REVV$ ) else { /* Addin as first node*/ pRew!3next ( p2ead$ p2ead ( pRew$ ) ) void insert:last"int val' { struct node *pRew, *p/emp$ pRew ( "struct node *'malloc"siYeof"struct node''$ pRew!3data ( val$ pRew!3next( REVV$

2. if "p2ead (( REVV' { /*Addin to e!"t# list*/ p2ead ( pRew$ p2ead!3next( REVV$ ) else { /* Addin as last node*/ p/emp ( p2ead$ while"p/emp!3nextI(REVV' p/emp ( p/emp!3next$ p/emp!3next ( pRew$ pRew!3next ( REVV$ ) ) Insertion a node into single lin# Vist" [eneral case' void insert:between"int val' { struct node *pRew, *p,re, *p/emp$ int #ey$ printf"N%nter the value after which node to be insertedO'$ scanf"NDdO, &#ey'$ // Allocate !e!or# for t$e ne% node pRew ( "struct node *'malloc"siYeof"struct node''$ pRew!3data ( val$ pRew!3next ( REVV$ if "p2ead (( REVV' { p2ead ( pRew$ p2ead!3next( REVV$ ) else { p/emp ( p2ead$ /* Searc$in while"p/empI(REVV' { if"p/emp!3data (( #ey' brea#$ else { p,re ( p/emp$ insertion "oint*/ /*Addin to e!"t# list*/

22 p/emp ( p/emp!3next$ ) ) if" p/emp((REVV' printf"N /he insertion point can+t be foundCnO'$ else { if " p/emp((p2ead' // inserted &efore $ead node { pRew!3next ( p/emp$ p2ead ( pRew$ ) else // insert as inter!ediate or last node { pRew!3next ( p/emp!3next$ p/emp!3next ( pRew$ ) ) ) ) (. Delete a node: Deleting a node requires that we logically remove the node from the list by changing various link pointers and then physically deleting the node from the heap. We can delete 1 the first node 2 any node in the middle 3 the end node o logically delete a node! 11. first locate the node itself " name the current node as "'e!" and its predecessor node as "(re. 12. change the predecessor#s link field to point to successor of the current node. 13. recycle the node $send it back to memory% using free. void delete "int #ey, struct node *p2ead' { struct node *p/emp, *p,re$ p/emp(p2ead$ if "p2ead (( REVV' printf"N %mpty lin#ed listCnO'$$ else // Searc$ node { p/emp ( p2ead$ while "p/empI(REVV'

20 { if"p/emp!3data (( #ey' brea#$ else { p,re ( p/emp p/emp ( p/emp!3next$ ) ) if" p/emp((REVV' printf"NRode not foundCnO'$ else { if " p/emp (( p2ead ' p2ead ( p/emp!3next$ else p,re!3next ( p/emp!3next$ free"p/emp' printf"NRode deletedCnO '$ ) ) ) +. Search for an item in the list: 'J Gi en the item and the pointer to the head of the list, the function returns a pointer to the node which matches the item, or returns C8BB if the item is not found J' .truct node *.earch "int item, struct node *p2ead' { struct node *p/emp$ int i(9$ p/emp(p2ead$ if "p2ead (( REVV' printf"N %mpty lin#ed listCnO'$$ else // Searc$ node { p/emp ( p2ead$ while "p/empI(REVV' { if"p/emp!3data (( #ey' brea#$ else { p/emp ( p/emp!3next$ i ( i 9$ )

2@ ) if" p/emp((REVV' printf"NRode can+t be foundCnO'$ else printf"NRode found at location DdCnO, i '$ ) return"p/emp' ) .. Counting the nodes in a %ist: int count"struct node *p2ead' { struct node * p/emp$ int c ( 8$ p/emp ( p2ead$ while "p/emp I( REVV' { c ( c 9$ p/emp ( p/emp!3next$ ) return c$ ) 5. Printing the contents of a list: o print the contents" traverse the list from the head node to the last node. void display" struct node *p2ead' { struct node *p/emp$ p/emp ( p2ead$ while "p/emp I( REVV' { printf"NDdO, p/emp !3 data'$ p/emp ( p/emp !3 next$ ) )

2I

2N 75 P*$)*A3 1$* 03P%,3, TAT0$ $1 S0 )%, %0 /,D %0ST 57 -includeAstdio.hA -include<alloc.h3 -define REVV 8 /* S')*+'*), +-.'A./.0 A 1A'A (A)' A.1 A 2/.3 (A)' */ struct node { int data$ struct node *next$ )*p2ead$ /* "$ead is a lo&al "ointer contains t$e adress of t$e first node in list*/ */

p2ead(REVV$ /* '4/S /S '4, 5A/. ()-0)A5 main"' { int i, num, loc$

while"9' /* t$is is an indefinite loo" */ { printf"A Cn9.IR.%R/ 5 RE4F%R 5/ F%[IRRIR[$CnA'$ printf"A >.IR.%R/ 5 RE4F%R 5/ V5./=CnA'$ printf"A ?.IR.%R/ 5 RE4F%R 5/ 5 ,5R/ISEV5R V1S5/I1R IR VI./=CnA'$ printf"A @.,RIR/ /2% %V%4%R/. IR /2% VI./ =CnA'$ printf"A 7.,RIR/ /2% RE4F%R 1U %V%4%R/. IR /2% VI./CnA'$ printf"A Z.0%V%/% 5 R10% IR /2% VIRX%0 VI./=CnA'$ printf"A \.[%/ 1E/ 1U VIRX%0 VI./=CnA'$ printf"A ,V%5.%, %R/%R /2% RE4F%R=CnA'$ scanf"ADdA,&i'$ /* %R/%R 5 H5VE% U1R .BI/S2 */ switch"i' { case 9= printf"A%R/%R /2% RE4F%R =!A'$ scanf"ADdA,&num'$ insert:begin"num'$ brea#$ case >= printf"A%R/%R /2% RE4F%R =!A'$ scanf"ADdA,&num'$ insert:last"num'$ brea#$ case ?=

2: printf"A ,V%5.% %R/%R /2% RE4F%R =!A'$ scanf"ADdA,&num'$ printf"A,V%5.% %R/%R /2% V1S5/I1R RE4F%R =!A'$ scanf"ADdA,&loc'$ insert:after"num,loc'$ brea#$ @= printf"A /2% %V%4%R/. IR /2% VI./ 5R% = A'$ display" '$ brea#$ 7= printf"A /otal Ro 1f %lements In /he Vist areDdA,count"''$ brea#$ Z= printf"A ,V%5.% %R/%R 5 RE4F%R to be deleted =A'$ scanf"ADdA,&num'$ delete"num'$ brea#$ \= exit"'$

case

case

case

case

) )

) /* end if s%itc$ */ /* end of %$ile */ /* end of !ain */

/* A11 A .,6 .-1, A' 7,0/../.0 */ void insert:begin"int val' { struct node *pRew$ pRew ( "struct node *'malloc"siYeof"struct node''$ pRew!3data ( val$ if "p2ead (( REVV' { /*Addin to e!"t# list*/ p2ead ( pRew$ p2ead!3next( REVV$ ) else { /* Addin as first node*/ pRew!3next ( p2ead$ p2ead ( pRew$ ) )

2; /*'4/S 8*.+'/-. A11S A .-1, A' '4, 2AS' -8 2/.3,1 2/S' */ void insert:last"int val' { struct node *pRew, *p/emp$ pRew ( "struct node *'malloc"siYeof"struct node''$ pRew!3data ( val$ pRew!3next( REVV$ if "p2ead (( REVV' { /*Addin to e!"t# list*/ p2ead ( pRew$ p2ead!3next( REVV$ ) else { /* Addin as last node*/ p/emp ( p2ead$ while"p/emp!3nextI(REVV' p/emp ( p/emp!3next$ p/emp!3next ( pRew$ pRew!3next ( REVV$ ) ) /*'4/S 8*.+'/-. 1,2,',S A .-1, */ void delete "int #ey, struct node *p2ead' { struct node *p/emp, *p,re$ p/emp(p2ead$ if "p2ead (( REVV' printf"N %mpty lin#ed listCnO'$$ else // Searc$ node { p/emp ( p2ead$ while "p/empI(REVV' { if"p/emp!3data (( #ey' brea#$ else { p,re ( p/emp p/emp ( p/emp!3next$ ) )

0/

if" p/emp((REVV' printf"NRode not foundCnO'$ else { if " p/emp (( p2ead ' p2ead ( p/emp!3next$ else p,re!3next ( p/emp!3next$ free"p/emp' printf"NRode deletedCnO '$ ) ) ) /* A11 A .,6 .-1, A8',) A S(,+/8/,1 .- -8 .-1,S */ insert:after"int num, int loc' { int i$ struct node *pRew,*p,re,*p/ur$ p/emp(phead$ /* $ere "'e!" stores t$e first location */ if"loc 3 count"' 9 KK loc <( 8' { printf"A insertion is not possible = A'$ return$ ) if "loc (( 9' /* if list is null t$en add at &e innin */ { insert:begin"num'$ return$ ) else { for"i(9$i<loc$i ' { ppre(pcur$ /* ppre will be holding previous value */ pcur(pcur!3next$ ) pnew("struct node *'malloc"siYeof"struct node''$ pnew!3data(num$ pnew!3next(ppre!3next ppre!3next(pnew$ return$ ) )

01 // A11 A .,6 .-1, A8',) A S(,+/8/,1 node 9alue */ void insert:byHalue"int val' { struct node *pRew, *p,re, *p/emp$ int #ey$ printf"N%nter the value after which node to be insertedO'$ scanf"NDdO, &#ey'$ // Allocate !e!or# for t$e ne% node pRew ( "struct node *'malloc"siYeof"struct node''$ pRew!3data ( val$ if "p2ead (( REVV' { p2ead ( pRew$ p2ead!3next( REVV$ ) else { p/emp ( p2ead$ /* Searc$in insertion "oint*/ while"p/empI(REVV' { if"p/emp!3data (( #ey' pRew!3next ( p/emp!3next$ p/emp!3next ( pRew else { p,re ( p/emp$ p/emp ( p/emp!3next$ ) ) if" p/emp((REVV' printf"N /he insertion point can+t be foundCnO'$ else { if " p/emp((p2ead' // inserted &efore $ead node { pRew!3next ( p/emp$ p/emp!3next ( pRew$ ) else // insert as inter!ediate or last node { pRew!3next ( p/emp!3next$ p/emp!3next ( pRew$ /*Addin to e!"t# list*/

0. ) ) ) ) /* '4/S 8*.+'/-. 1/S(2A:S '4, +-.',.'S -8 '4, 2/.3,1 2/S' */ void display" ' { struct node *p/emp$ p/emp(p2ead$ if"p/emp ((REVV' { printf"AR1 %V%4%R/ IR /2% VI./ =A'$ return$ ) else /* tra9erse t$e entire linked list */ while"p/empI(REVV' { printf"ADd CnA,r!3data'$ p/emp ( p/emp !3next$ ) )

//'4/S 8*.+'/-. +-*.'S '4, .*57,) -8 ,2,5,.'S /. '4, 2/S' void count"' { struct node *p/emp$ int c(8$ *p/emp(phead$ while"p/empI(REVV' { p/emp ( p/emp !3next$ c $ ) return"c'$ ) 5pplication of single lin#ed list= ,rogram to add two polynomials= e.g "Z6> ?6 9' "76? 76 ?' ( 76? Z6> M6 @ -include<stdio.h3 -include<alloc.h3

02 -include<conio.h3 struct node { int coeff$ int pow$ struct node *next$ )$ struct node *poly9(REVV,*poly>(REVV,*poly(REVV$ void create"struct node *n' { char ch$ do { printf"ACn enter coeff=A'$ scanf"ADdA,&node!3coeff'$ printf"ACn enter power=A'$ scanf"ADdA,&node!3pow'$ node!3next("struct lin#*'malloc"siYeof"struct lin#''$ node(node!3next$ node!3next(REVV$ printf"ACn continue"y/n'=A'$ ch(getch"'$ ) while"ch((GyG KK ch((GWG'$ ) void show"struct lin# *n' { while"n!3nextI(REVV' { printf"ADdxJDdA,n!3coeff,n!3pow'$ n(n!3next$ if"n!3nextI(REVV' printf"A A'$ ) ) void polyadd"struct node *poly9,struct node *poly>,struct node *poly' { while"poly9!3next && poly>!3next' { if"poly9!3pow3poly>!3pow' { poly!3pow(poly9!3pow$ poly!3coeff(poly9!3coeff$ poly9(poly9!3next$

00 ) else if"poly9!3pow<poly>!3pow' { poly!3pow(poly>!3pow$ poly!3coeff(poly>!3coeff$ poly>(poly>!3next$ ) else { poly!3pow(poly9!3pow$ poly!3coeff(poly9!3coeff poly>!3coeff$ poly9(poly9!3next$ poly>(poly>!3next$ ) poly!3next("struct node *'malloc"siYeof"struct node''$ poly(poly!3next$ poly!3next(REVV$ ) while"poly9!3next KK poly>!3next' { if"poly9!3next' { poly!3pow(poly9!3pow$ poly!3coeff(poly9!3coeff$ poly9(poly9!3next$ ) if"poly>!3next' { poly!3pow(poly>!3pow$ poly!3coeff(poly>!3coeff$ poly>(poly>!3next$ ) poly!3next("struct node *'malloc"siYeof"struct node''$ poly(poly!3next$ poly!3next(REVV$ ) ) main"' { char ch$ poly9("struct lin# *'malloc"siYeof"struct lin#''$ poly>("struct lin# *'malloc"siYeof"struct lin#''$ poly("struct lin# *'malloc"siYeof"struct lin#''$ printf"ACnenter 9st number=A'$

0@ create"poly9'$ printf"ACnenter >nd number=A'$ create"poly>'$ printf"ACn9st Rumber=A'$ show"poly9'$ printf"ACn>nd Rumber=A'$ show"poly>'$ polyadd"poly9,poly>,poly'$ printf"ACn5dded polynomial=A'$ show"poly'$ getch"'$ )

0I C0*C!%A* %0 /,D %0ST: The circular linked list is similar to single linked list e%cept that the last nodeZs ne%t pointer points to the first node. &n a circularly linked list, all nodes are linked in a continuous circle, without using null.

Parious operations that can be performed with circular linked list are =reation of circular linked list &nsertion of a node in circular linked list Deletion of any node from the list Display of circular linked list //Sircular Vin#ed Vist in S -include<stdio.h3 -include<conio.h3 -include<stdlib.h3 -include<alloc.h3 -define REVV 8 struct node { int data$ struct node *next$ )$ struct node *p2ead$ void main"' { int ch,n,m,#ey,i,cou p2ead ( REVV$ while"9' { printf"A 9. SR%5/% 5 VI./ CnO'$ printf"A >.IR.%R/ 5 RE4F%R 5/ F%[IRRIR[$CnA'$ printf"A ?.IR.%R/ 5 RE4F%R 5/ V5./=CnA'$ printf"A @.IR.%R/ 5 RE4F%R 5U/%R 5 ,5R/ISEV5R H5VE% IR VI./=CnA'$ printf"A 7.0%V%/% 5 R10% IR /2% VIRX%0 VI./=CnA'$ printf"A Z.,RIR/ /2% %V%4%R/. IR /2% VI./ =CnA'$ printf"A \.,RIR/ /2% RE4F%R 1U %V%4%R/. IR /2% VI./CnA'$ printf"A M.[%/ 1E/ 1U VIRX%0 VI./=CnA'$ printf"A ,V%5.%, %R/%R /2% RE4F%R=CnA'$ scanf"ADdA,&ch'$ switch"ch'

0N { case 9= printf"Aenter no of itemsA'$ scanf"ADdA,&n'$ for"i(8$i<n$i ' { printf"Aenter the elementA'$ scanf"ADdA,&m'$ create"m'$ ) brea#$ case >= printf"Aenter the elementA'$ scanf"ADdA,&m'$ insert:begin"m'$ brea#$ case ?= printf"Aenter the elementA'$ scanf"ADdA,&m'$ insert:last"m'$ brea#$ case @= printf"Aenter the elementA'$ scanf"ADdA,&m'$ printf"Aenter the value after which you want to insertA'$ scanf"ADdA,&#ey'$ insert:after"m,#ey'$ brea#$ case 7= printf"A%nter the element to deleteA'$ scanf"ADdA,&m'$ delete"m'$ brea#$ case Z= display"'$ brea#$ case \= cou(count"'$ printf"ARo. of elements in the listDd A, cou'$ brea#$ case M= exit"8'$ brea#$ default= printf"Awrong choiceA'$ ) ) ) // Uunction to create circular list

0: create"int data' { struct node *pRew,*p/emp$ pRew ("struct node *'malloc"siYeof"struct node''$ pRew !3data(data$ pRew !3next(REVV$ if"p2ead (( REVV' { p2ead ( pRew$ pRew !3next( p2ead$ ) else { p/emp ( p2ead$ while"p/emp!3nextI(p2ead' p/emp ( p/emp!3next$ p/emp!3next ( pRew$ pRew!3next ( p2ead$ ) return$ ) /* 500 5 R%B R10% 5/ F%[IRRIR[ */ insert:begin"int val' { struct node *pRew, *p/emp$ pRew ( "struct node *'malloc"siYeof"struct node''$ pRew!3data ( val$ if "p2ead (( REVV' { /*5dding to empty list*/ p2ead ( pRew$ p2ead!3next( pRew$ printf"ARode insertedCnA'$ ) else { /* 5dding as first node*/ p/emp ( p2ead$ while"p/emp!3nextI(p2ead' p/emp ( p/emp!3next$ p/emp!3next ( pRew$ pRew!3next ( p2ead$ p2ead ( pRew$ printf"ARode insertedCnA'$ ) return$ )

0; /*/2I. UERS/I1R 500. 5 R10% 5/ /2% V5./ 1U VIRX%0 VI./ */ insert:last"int val' { struct node *pRew, *p/emp$ pRew ( "struct node *'malloc"siYeof"struct node''$ pRew!3data ( val$ if "p2ead (( REVV' { /*5dding to empty list*/ p2ead ( pRew$ p2ead!3next( p2ead$ ) else { /* 5dding as last node*/ p/emp ( p2ead$ while"p/emp!3nextI(p2ead' p/emp ( p/emp!3next$ p/emp!3next ( pRew$ pRew!3next ( p2ead$ printf"NRode insertedCnO'$ ) return$ ) /* 500 5 R%B R10% 5U/%R 5 .,%SIUI%0 H5VE% IR /2% VI./ */ insert:after"int val, int #ey' { struct node *pRew, *p,re, *p/emp$ // 5llocate memory for the new node pRew ( "struct node *'malloc"siYeof"struct node''$ pRew!3data ( val$ if"p2ead (( REVV' /*5dding to empty list*/ { p2ead ( pRew$ p2ead!3next( pRew$ ) else { p/emp ( p2ead$ /* .earching insertion point*/ do { if"p/emp!3data (( #ey' { pRew!3next ( p/emp!3next$ p/emp!3next ( pRew$ printf"Anode insertedA'$ return$

@/ ) else { p/emp ( p/emp!3next$ ) ) while"p/empI(p2ead'$ if" p/emp((p2ead' printf"A /he insertion point can+t be foundCnO'$ ) return$ ) /* /2I. UERS/I1R 0I.,V5W. /2% S1R/%R/. 1U /2% VIRX%0 VI./ */ display" ' { struct node *p/emp$ p/emp(p2ead$ if"p/emp ((REVV' { printf"AR1 %V%4%R/ IR /2% VI./ =A'$ return$ ) else /* traverse the entire lin#ed list */ do { printf"ADd CnA, p/emp !3data'$ p/emp ( p/emp !3next$ ) while"p/empI(p2ead'$ return$ ) ///2I. UERS/I1R S1ER/. /2% RE4F%R 1U %V%4%R/. IR /2% VI./ int count"' { struct node *p/emp$ int c(9$ p/emp(p2ead$ if "p2ead ((REVV' return 8$ while"p/emp!3nextI( p2ead' { p/emp ( p/emp !3next$ c $ ) return"c'$ )

@1 /*/2I. UERS/I1R 0%V%/%. 5 R10% */ delete"int #ey' { struct node *pRew, *p,re, *p/emp$ if "p2ead (( REVV' /*0%V%/I1R in empty list*/ { printf"A %mpty lin#ed list CnO'$ ) else { p/emp ( p2ead$ /* .earching 0%V%/I1R point*/ do { if"p/emp!3data (( #ey' { if"p/emp((p2ead && p/emp!3next((p2ead' { free"p/emp'$ /* deleting only node existing in the lin# p2ead(REVV$ printf"Nnode deleted CnA'$ return$ ) else if"p/emp((p2ead && p/emp!3nextI(p2ead' { while"p/emp!3next I( p2ead' /*delete head node p/emp ( p/emp!3next$ p/emp!3next ( p2ead!3next$ free"p2ead'$ p2ead ( p/emp!3next$ printf"Ahead node deleted CnA'$ return$ ) else { p,re!3next ( p/emp!3next$ free"p/emp'$ printf"Anode deleted CnA'$ return$ ) ) else { p,re ( p/emp$ p/emp ( p/emp!3next$ ) ) while"p/empI(p2ead'$

@. if" p/emp((p2ead' printf"A /he deletion point can+t be foundCnA'$ ) return$ )

@2 Application of Circular %in9ed %ist: DosephusE Problem: This algorithm is named for a historian of the first century, 5la ius [osephus, who sur i ed the [ewish(oman war due to his mathematical talents. Begend has it that he was one out of 01 [ewish rebels trapped by the (omans. 6is companions preferred suicide to escape, so they decided to form a cycle and to kill e ery third person and to proceed around the circle until no one was left. [osephus wasn9t e%cited by the idea of killing himself, so he calculated where he has to stand to sur i e the icious circle. Algorithm: There are n people standing in a circle waiting to be e%ecuted. After the first man is e%ecuted, k\1 people are skipped and the k-th man is e%ecuted. Then again, k\1 people are skipped and the k-th man is e%ecuted. The elimination proceeds around the circle *which is becoming smaller and smaller as the e%ecuted people are remo ed+, until only the last man remains, who is gi en freedom. &n $uclidean geometry, a circle is the set of all points in a plane at a fi%ed distance, called the radius, from a fi%ed point, called the centre. ... The task is to choose the place in the initial circle so that you sur i e *remain the last one+, gi en n and k. 1or s9ip 2alue 9 = .< n=F 1 : 2 N 0 I @ N I @ Delete*0+ 1 N I Delete*@+ . 2 N I Delete*.+ 1 2 2 N I delete*1+ delete*:+ : 2 N I @ 2 . 1 .

N I Delete*2+ I delete*N+, sur i ed ? I

@0 Program to implement Dosophus Problem: -include <stdio.h3 -include<stdlib.h3 -define REVV 8 struct node { int soilder$ struct node *next$ )$ struct node *head, *current$ int tot:soilders$ main"' { int ch,n$ head ( REVV$ while"9' { printf"ACn9. soilder list creationA'$ printf"ACn>. 0isplay soilder listA'$ printf"ACn?. .ucideA'$ printf"ACn8. %xitA'$ scanf"ADdA,&ch'$ switch"ch' { case 9= printf"ACn%nter the total no. of soildersA'$ scanf"ADdA,&n'$ create:list"n'$ brea#$ case >= display"'$ getch"'$ brea#$ case ?= if "tot:soilders <( 9' printf"A/here .hould Fe 5tleast > .oilders in the VistA'$ else { printf"ACn%nter the no by which sucide is to be commitedA'$ scanf"ADdA,&n'$ if " n < 9 ' printf"ACnInvalid RumberIA'$ else printf"ACn/he only .oilder left after sucide session is Dd A,left:after:sucide"n''$ )

@@ getch"'$ brea#$ case 8= return$ default = printf"ACnIRH5VI0 S21IS%A'$ getch"'$ ) ) ) create:list"int data' { struct node *last,*Rew$ int i$ head(REVV$ for"i(9$i<(data$i ' { Rew("struct node *'malloc"siYeof"struct node''$ Rew!3soilder(i$ Rew!3next(REVV$ tot:soilders(tot:soilders 9$ if"head((REVV' { head(Rew$ last(Rew$ Rew!3next(head$ ) else { Rew!3next(last!3next$ last!3next(Rew$ last ( Rew$ ) ) ) display"' { if "head (( REVV' { printf"ACnRo .oilders in the TueueA'$ return$ ) printf"ADdA,head!3soilder'$ printf"ADc A,>'$ current ( head!3next$ while" current I( head' { printf"ADd A,current!3soilder'$

@I current ( current!3next$ ) return$ ) int left:after:sucide"int by:n' { int i(9,],dead:sol$ struct node *save$ current ( head$ for"i(9$ i<tot:soilders$ i ' { for "](9$]< by:n$] ' { save ( current$ current ( current!3next$ ) save!3next ( current!3next$ if "current (( head' { head ( current!3next$ ) dead:sol ( current!3soilder$ free"current'$ display"'$ printf"ACnCnDdDc is 0ead CnA,dead:sol,9'$ current ( save!3next$ ) head ( current$ display"'$ tot:soilders ( 9$ return"head!3soilder'$ )

@N Doubly %in9ed %ists Doubly %in9ed %ist *DBB+ is a type of Binked Bist in which each data item points to the ne%t and also to the pre ious data item. This 4linking4 is accomplished by keeping two address ariables *pointers+ together with each data item. These pointers are used to store the address of the pre ious and the address of the ne%t data items in the list. The structure that is used to store one element of a linked list is called a node like in Binked Bists. A node has three parts! data, pre2ious address and next address. The data part contains the necessary information about the items of the list, the pre ious address part contains the address of the pre ious node, the ne%t address part contains the address of the ne%t node.

"asic double lin9ed list fragment:


-include<stdio.h3 -include<conio.h3 -include<alloc.h3 struct node { int no$ struct node *pre,*next$ )$ struct node *head(REVV,*tail(REVV$ void main"' { int ch$ clrscr"'$ do { printf"ACnCnCn 9 5ppendA'$

@: printf"ACn > Uorward /raverseA'$ printf"ACn ? Insert after the given numberA'$ printf"ACn @ Insert before the given numberA'$ printf"ACn 7 Insert Fy ,osition A'$ printf"ACn Z 0elete Fy Halue A'$ printf"ACn \ 0elete by ,ositionA'$ printf"ACn 8 %6I/A'$ printf"ACn %nter your choiceA'$ scanf"ADdA,&ch'$ switch"ch' { case 9= 5ppend"'$ brea#$ case >= ftraverse"'$ brea#$ case ?= insertafter"'$ brea#$ case @= insertbefore"'$ brea#$ case 7= insertbypos"'$ brea#$ case Z= delFyHalue"'$ brea#$ case \= delFy,os"'$ brea#$ case 8= brea#$ default= printf"ACn Invalid ShoiceA'$ ) )while"chI(8'$ getch"'$ ) // 5ppending a new node void 5ppend"' { struct node *pRew$

@; pRew ("struct node*'malloc"siYeof"struct node''$ printf"ACn%nter noA'$ scanf"ADdA,& pRew !3no'$ pRew !3next(REVV$ if"head((REVV' { head( pRew$ tail( pRew$ head!3pre(REVV$ return$ ) tail!3next( pRew$ pRew !3pre(tail$ tail( pRew$ ) //0isplaying the contents of the list void ftraverse"' { struct node *p(head$ if"head((REVV' { printf"ACn %mpty Vin# VistA'$ return$ ) while"pI(REVV' { printf"A DdA,p!3no'$ p(p!3next$ ) ) // Inserting a node after a specified number in the node // Insert by number void insertafter"' { int val$ struct node *p (head,* pRew$ if"head((REVV' { printf"ACn%mpty VIRX lI./A'$ return$ ) printf"ACn %nter number after which you want to IR.%R/A'$ scanf"ADdA,&val'$ if"val((tail!3no'

I/ { pRew ("struct node*'malloc"siYeof"struct node''$ printf"ACn%R/%R numberA'$ scanf"ADdA,& pRew !3no'$ tail!3next( pRew$ pRew !3pre(tail$ tail( pRew$ tail!3next(REVV$ printf"ACn R10% IR.%R/%0A'$ return$ ) while"p!3nextI(REVV' { if"val((p!3no' { pRew ("struct node*'malloc"siYeof"struct node''$ printf"ACn%nter numberA'$ scanf"ADdA,& pRew !3no'$ pRew !3next(p!3next$ pRew !3pre(p$ p!3next( pRew$ pRew !3next!3pre( pRew$ printf"ACn Rode InsertedA'$ return$ ) p(p!3next$ ) printf"ACnDd Rumber Rot foundA,val'$ return$ ) // Insert a node before a specified number void insertbefore"' { int val$ struct node *p (head,* pRew$ if"head((REVV' { printf"ACn%mpty VIRX lI./A'$ return$ ) printf"ACn %nter number F%U1R% which you want to IR.%R/A'$ scanf"ADdA,&val'$ if"val((head!3no'

I1 { pRew ("struct node*'malloc"siYeof"struct node''$ printf"ACn%R/%R numberA'$ scanf"ADdA,& pRew !3no'$ head!3pre( pRew$ pRew !3next(head$ head( pRew$ head!3pre(REVV$ printf"ACn R10% IR.%rtedA'$ return$ ) while"pI(REVV' { if"val((p!3no' { pRew ("struct node*'malloc"siYeof"struct node''$ printf"ACn%R/%R numberA'$ scanf"ADdA,& pRew !3no'$ pRew !3pre(p!3pre$ pRew !3next(p$ pRew !3pre( pRew$ pRew !3pre!3next( pRew$ printf"ACn Rode insertedA'$ return$ ) p(p!3next$ ) printf"ACnDd Rumber not foundA,val'$ return$ ) // Insert a new node after a specified position in the list void insertbypos"' { int val$ struct node *p (head,* pRew$ int non(8,i,pos$ if"head((REVV' { printf"ACn%mpty VIRX lI./A'$ return$ ) printf"ACn%nter the positionA'$

I. scanf"ADdA,&pos'$ while"pI(REVV' { non $ p(p!3next$ ) if "pos<9&&pos3non 9' { printf"ACn Invalid ,ositionA'$ return$ ) if"pos((9' { pRew ("struct node*'malloc"siYeof"struct node''$ printf"ACn%R/%R numberA'$ scanf"ADdA,& pRew !3no'$ head!3pre( pRew$ pRew !3next(head$ head( pRew$ head!3pre(REVV$ printf"ACn Rode insertedA'$ return$ ) if"pos((non 9' { pRew ("struct node*'malloc"siYeof"struct node''$ printf"ACn%nter numberA'$ scanf"ADdA,& pRew !3no'$ tail!3next(n$ pRew !3pre(tail$ tail( pRew$ tail!3next(REVV$ printf"ACn Rode insertedA'$ return$ ) p(head$ for"i(9$i<pos!9$i ' { p(p!3next$ ) pRew ("struct node*'malloc"siYeof"struct node''$ printf"ACn%R/%R numberA'$ scanf"ADdA,& pRew !3no'$ pRew !3next(p!3next$

I2 pRew !3pre(p$ p!3next( pRew$ pRew !3next!3pre( pRew$ printf"ACn R10% InsertedA'$ return$ ) // 0elete a node with specified number in the node void delFyHalue"' { int val$ struct node *p (head$ int i,pos$ if"head((REVV' { printf"ACn%mpty VIRX lI./A'$ return$ ) printf"ACn%nter the number to be deletedA'$ scanf"ADdA,&val'$ if"head((tail&&val((head!3no' { free"p'$ head(tail(REVV$ printf"ACnRode 0eletedA'$ return$ ) else if "val((head!3no' { head(head!3next$ head!3pre(REVV$ free"p'$ printf"ACnRode 0eletedA'$ return$ ) else if"val((tail!3no' { p(tail$ tail(tail!3pre$ tail!3next(REVV$ free"p'$ printf"ACnRode 0eletedA'$ return$

I0 ) while"p!3nextI(REVV' { if"val((p!3no' { p!3pre!3next(p!3next$ p!3next!3pre(p!3pre$ free"p'$ printf"ACnRode 0eletedA'$ ) p(p!3next$ ) printf"ACn Rode not UoundA' $ return$ ) // 0elete a node by position void delFy,os"' { struct node *p (head$ int non(8,i,pos$ if"head((REVV' { printf"ACn%mpty VIRX lI./A'$ return$ ) printf"ACn%nter the ,1.I/I1R which is to be deletedA'$ scanf"ADdA,&pos'$ while"pI(REVV' { non $ p(p!3next$ ) p(head$ if"pos<9KKpos3non'$ { printf"ACn IRvalid ,ositionA'$ ) if"head((tail&&pos((9' { free"p'$ head(tail(REVV$ printf"ACnR10% 0eletedA'$ return$

I@ ) else if "pos((9' { head(head!3next$ head!3pre(REVV$ free"p'$ printf"ACnRode 0%VetedA'$ return$ ) else if"pos((non' { p(tail$ tail(tail!3pre$ tail!3next(REVV$ free"p'$ printf"ACnRode 0%VetedA'$ return$ ) for"i(8$i<pos!9$i ' { p(p!3next$ ) p!3pre!3next(p!3next$ p!3next!3pre(p!3pre$ free"p'$ printf"ACnRode 0eletedA'$ return$ ) Application : <alindrome checking using doubly linked list %in9ed %ist problems: '. 0mplement stac9 using lin9ed list (. 0mplement ;ueue using lin9ed list

II

T*,,S
Tree definitions A tree is a multi-linked data structure consisting of nodes with pointers to two or more other nodes. The connecting pointers between nodes are typically called tree e"ges. A tree has a distinguished node called its root to which no other node points. (ecursi ely, a tree can be defined as empty, or a root node with edges to zero or more subtrees.

Tree 2ie&s There are a number of ways to depict trees in graphic form. The nodes are represented as labeled circles and edges are connecting lines1 e.g.,

The linked list implementation of a tree is shown below

Array implementation of tree is shown below a b e c d f g

AV/W AV1W AV.W AV2W AV0W AV@W AVIW

IN Terminology 1. Root: The topmost node of the tree is the root. *or+ A node that doesnZt ha e a parent is a root node. .. Leaf: A node that doesnZt ha e children is called leaf node. 2. Siblings: Codes with a common parent are called siblings. 0. An upper node in the tree is the parent of the nodes immediately below it, and those lower nodes are the chil"ren. @. A node is the gran"parent of nodes two le els below, etc. I. Path: A path is a se#uence of nodes connected by edges. N. Height: The height of a node is the length of the longest path from the node to a leaf. :. Depth: The "epth of a node is the length of the path from the root to that node This terminology is illustrated in 5igure 1.

5igure 1! Tree terminology. The following are important tree facts. 1. .. 2. $ ery node e%cept the root has e%actly one parent. The root has no parent. There is a uni#ue path from the root to any node. &n tree e%amples abo e, each node had two children1 such trees are called binary. &n general, a tree node may ha e any number of children, from / to n1 such trees are called n,ary. 5igure . is an e%ample of an n-ary tree,

I:

5igure .! $%ample n-ary tree.

,xamples of tree#structured hierarchies! -. Directory Hierarchies! &n computers, files are stored in directories that form a tree. The top le el directory represents the root. &t has many subdirectories and files. The subdirectories would ha e further set of subdirectories. .. Organization charts& &n a company a number of ice presidents report to a president. $ach P< would ha e a set of general managers, each GD ha ing his'her own set of specific managers and so on. /. Biological classifications! "tarting from li ing being at the root, such a tree can branch off to mammals, birds, marine life etc. 0. a!e "rees: All games which re#uire only mental effort would always ha e number of possible options at any position of the game. 5or each position, there would be number of counter mo es. The repetiti e pattern results in what is known a game tree. "inary Trees Definition: A binary tree is a tree in which each node can ha e ma%imum two children. Thus each node can ha e no child, one child or two children. The pointers help us to identify whether it is a left child or a right child. ,xamples of binary trees!

The following are $T binary trees!

I;

The le2el of a node in a binary tree: The root of the tree has le el / The le el of any other node in the tree is one more than the le el of its parent.

umber of nodes in each le2el are Be el / : 1 node Be el 1 ! . nodes Be el . ! 0 nodes Be el 2 ! : nodes

N/

Total number of nodes for this tree ? 1@ 6eight of the root node ? 2 n ? .2A1 Q 1 ? 1@ &n general, n ? .hA1 Q 1 * ma%imum+ 3aximum umber of nodes in a tree &ith height h is n = (h6' 4 ' Aeight of a tree &ith n nodes : h = log ( n6') # ' 0mplementation A binary tree has a natural implementation in linked storage. A tree is referenced with pointer to its root. *ecursi2e definition of a binary tree! A binary tree is either ; $mpty, or ; A node *called root+ together with two binary trees *called left subtree and the right subtree of the root+ $ach node of a binary tree has both left and right sub trees which can be reached with pointers Structure of a &inar# tree struct tree<node = int data; struct tree<node *left<c$ild; struct tree<node *ri $t<c$ild; >;

Tree tra2ersal: Tree tra ersal is the process of isiting each node in the tree e%actly once. Types of tree tra ersal! * Depth first tree tra ersing+ 1. <reoder tra ersal! * (oot Beft Pisit the root node. (ight +

N1 Tra erse the left subtree. Tra erse the right subtree. .. &norder tra ersal! * Beft (oot (ight + Tra erse the left subtree. Pisit the root node. Tra erse the right subtree. 2. <ostorder tra ersal! * Beft (ight (oot + Tra erse the left subtree. Tra erse the right subtree. Pisit the root node. 0. Be el order tra ersal! *,readth 5irst Tree Tra ersal + Tra erse the nodes from le el / to le el n $.g "uppose there are only 2 nodes in the tree ha ing the following arrangement!

&n order! n. ] n1 ] n2 <re order! n1 ] n. ] n2 <ost order! n. ] n2 ] n1 Algorithm for Preorder tra2ersal of a binary tree: &f the root node of the tree is null, the tra ersal is done. )therwise, isit the root node. Then recursi ely tra erse the left subtree. i-e &f there is a left child we isit the left subtree *all the nodes+ in pre-order fashion starting with that left child . Then recursi ely tra erse the right subtree. i-e &f there is a right child then we isit the right subtree in pre-order fashion starting with that right child. void preorder"struct tree:node * p' { if "p I(REVV' { printf"NDdCnO, p!3data'$ preorder"p!3left:child'$

N. preorder"p!3right:child'$ ) ) ,xample!

Preorder Tra ersal ! a b c d f g e a*root+ b*left+ c d f g e *right+ 0n#order tra2ersal of a binary tree &f the root node of the tree is null, the tra ersal is done. Tra erse the left subtree recursi ely. i-e &f there is a left child we isit the left subtree *all the nodes+ in in-order fashion. Pisit the root node. Then recursi ely tra erse the right subtree. i-e &f there is a right child then we isit the right subtree in in-order fashion. void inorder"struct tree:node *p' { if "p I(REVV' { inorder"p!3left:child'$ printf"NDdCnO, p!3data'$ inorder"p!3right:child'$ ) )

0norder!

bafdgce

N2 b*left+ a*root+ f d g c e*right+ Algorithm for Post order tra2ersal of a binary tree: &f the root node of the tree is null, the tra ersal is done. (ecursi ely tra erse the left subtree. i-e &f there is a left child we isit the left subtree *all the nodes+ in pre-order fashion starting with that left child . Then recursi ely tra erse the right subtree. i-e &f there is a right child then we isit the right subtree in pre-order fashion starting with that right child. At last isit the root node. void postorder"struct tree:node * p' { if "p I(REVV' { preorder"p!3left:child'$ preorder"p!3right:child'$ printf"NDdCnO, p!3data'$ ) ) ,xample!

Post order : b f g d e c a b (left) f g d e c (Right) a ( Root ) Level order: abcdefg a (level 0) b c (level 1) d e (level 2) f g (level 3)

1inding sum of the 2alues of all the nodes of a tree: To find the sum, add to the alue of the current node, the sum of alues of all nodes of left subtree and the sum of alues of all nodes in right subtree. int sum(struct tree_node * )

N0 ! if ( "# $%LL) return( &'data ( sum( &'left_child)( sum( &'right_child))) else return 0) *

,xpression Trees

,xpression tree for (a 6 b 5 c) 6 ((d 5 e 6 f ) 5 g) The abo e figure shows an e%ample of an e%pression tree . The lea es of an e%pression tree are operands , such as constants or ariable names, and the other nodes contain operators . This particular tree is a binary tree, because all of the operations are binary, and although this is the simplest case, it is possible for nodes to ha e more than two children. &t is also possible for a node to ha e only one child, as is the case with the unary minus operator. -e can e aluate an e%pression tree, T, by applying the operator at the root to the alues obtained by recursi ely e aluating the left and right subtrees. &n our e%ample, the left subtree e aluates to a A *b J c+ and the right subtree e aluates to **d Je + A f + Jg. The entire tree therefore represents *a A *bJc++ A ***d J e + A f+J g+.

Constructing an ,xpression Tree


Algorithm for con2erting postfix expression into an expression tree: read the e%pression one symbol at a time. &f the symbol is an operand, create a one-node tree and push a pointer to it onto a stack. &f the symbol is an operator, pop pointers to two trees T1 and T. from the stack *T1 is popped first+. 5orm a new tree whose root is the operator and whose left and right children point to T. and T1 respecti ely. A pointer to this new tree is then pushed onto the stack. $%ample, suppose the input is a b c d e * *

N@ 1. The first two symbols are operands, so we create one-node trees and push pointers to them onto a stack.J J5or con enience, we will ha e the stack grow from left to right in the diagrams.

.. Ce%t, a 9A9 is read, so two pointers to trees are popped, a new tree is formed, and a pointer to it is pushed ontothe stack.J

2. Ce%t, c, d, and e are read, and for each a one-node tree is created and a pointer to the corresponding tree is pushed onto the stack.

0. Cow a 9A9 is read, so two trees are merged.

=ontinuing, a 9J9 is read, so we pop two tree pointers and form a new tree with a 9J9 as root.

NI

5inally, the last symbol is read, two trees are merged, and a pointer to the final tree is left on the stack.

NN

"inary search trees


A binary search tree *"ST+ or ordered binary tree is a node-based binary tree data structure which has the following properties!

The left subtree of a node contains only nodes with keys less than the node9s key. The right subtree of a node contains only nodes with keys greater than the node9s key. ,oth the left and right subtrees must also be binary search trees. %eft subtree G *oot G *ight subtree

$.g binary search tree The most appealing property of a binary search tree is that searching for a particular node can be performed using the following algorithm! ^ &f the alue we9re searching for is at the root, success. ^ )therwise, if the alue is less than the root, search the left subtree. ^ )therwise, search the right subtree. &f the tree is reasonably well balanced, this algorithm can operate in logarithmic time. This is the case because at each step in the search, half of the tree is eliminated from consideration. This is the same kind of logarithmic beha ior we saw in the binary search of a linear list.

Tree balancing: The logarithm search beha ior on a binary search tree only happens when the tree is reasonably well balanced. 4(easonably well balanced4 means that )*C'.+ of the nodes are in each half of the tree. The binary search tree property by itself does not guarantee a balanced tree. 5or e%ample, 5igure below shows degenerate 4left hea y4 and 4right hea y4 binary search trees.

N:

&n both of these trees, search time is )*C+, not )*log C+. This is because the 4eliminate half the tree4 step in the search algorithm ends up eliminating nothing "o in the worst case, all C nodes of the tree must be searched to find the alue at a leaf node. The key to keeping a binary search tree useful is to maintain balance. This can be done by a global balancing algorithm, that takes any binary search tree and redistributes all of its nodes into a ma%imally well balanced tree. The problem with global balancing is that it is as e%pensi e timewise as a complete sort. A more sensible approach is to maintain balance incrementally, not allowing the tree e er to get too far out of balance. $ach time a node is inserted or remo ed from the tree, the tree balance is adGusted.

Tra2ersal of a "inary Search Tree: The abo e ,"T can be tra ersed starting with the root node (*reor"er tra1ersal) to result in the se#uence @., 2., .@, 1/, .:, N@, I:, I2, @:, N/, ;I. 6owe er, an interesting feature is re ealed with the 2nor"er Tra1ersal which yields 1/, .@, .:, 2., @., @:, I2, I:, N/, N@, ;I This is nothing but an ordered listing of the alues of ,"T nodes in the increasing order, with the left most node being the smallest element and the right most node being the largest element. 0nserting a node in a "ST: &nsertion of a new node in a ,"T has to be done only at the appropriate place for it, so that o erall ,"T structure is still maintained, i.e. the alue at any node should be less than that at right node and less than that at the left node. &nserting a new node into a ,"T al&ays occurs at a C8BB pointer. There is ne er a case when e%isting nodes need to be rearranged to accommodate the new node. As an e%ample, consider inserting the new alue 02 into the ,"T shown abo e.

N;

Aint! "earch for node containing 02. )b iously you wonZt find it, but the search algorithm has taken you to the C8BB pointer where it should be placed, which is the right pointer of 2..

#nserting a new $al%e in a BS": The following function inserts a alue RdS in its proper place in a ,inary "earch Tree (with "istinct 1alues in the no"es3 no repeate" 1alues). recursi ely searches for the proper place to insert the new alue, and returns with a pointer to the position of the new node. a new node is created and the alue is stored in it. * the new node gets automatically linked to its parent node.+ ''&nserts a node with alue d in a tree with root p struct treenode { int data$ struct treenode *left$ struct treenode *right$ )$ struct treenode* insert" int d , struct treenode * p' { //Inserting the value in a new node if" p(( null' { p ( "struct treenode*'"malloc"siYeof"struct treenode'''$ p!3data ( d$ p!3left ( REVV$

:/ p!3right ( REVV$ ) //Inserting a value less than the root value, move left else { if"d < p!3data' p!3left ( insert" d, p!3left'$ //Inserting a value greater than the root value, move right else if"d 3 p!3data' p!3right ( insert" d, p!3right '$ ) return p$ ) Creating a "inary Search Tree: To create a binary search tree, keep on inserting the nodes as and when they arri e. Cote that the shape of the ,"T will depend on the order of insertion of the nodes. The earlier ,"T tree was created from the se#uence @., 2., .@, N@, I:, ;I, I2, 1/, N/, .:, @: &f the alues arri ed in the following se#uence! 1/, .@, .:, 2., @., @:, I2, I:, N/, N@, ;I the ,"T would take the following shape

1inding 3inimum 2alue in a tree: To perform 5indDin, "tart at the root Tra erse the left subtree until a left leaf *child+ is reached. (ecursi e implementation of findXmin for binary search trees! struct treenode* find:min"struct treenode* / ' { if" / (( REVV ' return REVV$

:1 else if" /!3left (( REVV ' return" / '$ else return" find:min " /!3left ' '$ ) This function returns tree node with minimum alue. onrecursi2e implementation of findHmin for binary search trees: struct treenode* find:min"struct treenode* / ' { if" / I( REVV ' while" /!3left I( REVV ' / ( /!3left$ return /$ ) 1inding 3aximum 2alue in a tree: To perform 5indDa% "tart at the root Tra erse the right subtree until a right leaf *child+ is reached. 77 This function returns tree node &ith maximum 2alue struct treenode* find:min"struct treenode* / ' { if" / (( REVV ' return REVV$ else if" /!3right (( REVV ' return" / '$ else return" find:min " /!3right' '$ ) 77 onrecursi2e implementation of findHmax for binary search trees: struct treenode* find:min"struct treenode* / ' { if" / I( REVV ' while" /!3right I( REVV ' / ( /!3right$ return /$ )

:.

Searching for a target in the "inary Search Tree: The binary search tree definition allows you to #uickly search for a particular alue in the ,"T. =heck the gi en alue with the alue in the root node. &f it matches, return p, else if the gi en alue is smaller than the root alue, look into the left subtree, else look into the right subtree. &f subtree is null, return /. struct treenode *tree.earch" struct treenode *p, int target' { if "pI(REVV' { if "p!3data (( target' return p$ else if "p!3data 3 target' return tree.earch"p!3left, target'$ else return tree.earch"p!3right, target'$ ) return 8$ ) Apply this function on the binary search tree shown earlier to locate I2. &t re#uires to search, Gust 0 nodes to locate the alue. &f the tree is balanced the time comple%ity of searching should be O(log n), where n is the number of nodes on the tree. &n the worst case, when the tree is skewed in one direction, it would be O(n). Creating a balanced tree from sorted data: The abo e tree is not a balanced tree, but skewed towards right, as all the elements are in perfectly sorted order. &n such a case, the search and insertion comple%ity would be )*n+ instead of )*log n+. &f the se#uence were entered in descending order then it would result in a left-skewed tree. 5or any other ordering of the se#uence the comple%ity would lie in between )*n+ and )*log n+. To generate a balanced ,"T, gi en any arbitrary se#uence of alues, storing all the elements in an array and sorting them in ascending order. )nce sorted, the element at the midpoint of the array is chosen as the root of the ,"T. The array can now be iewed as consisting of two subarrays, one to the left of the midpoint and one to the right of the midpoint. The middle element in the left subarray becomes the left child of the root node and the middle element in the right subarray becomes the right child of the root.

:2 This process continues with further subdi ision of the original array until all the elements in the array ha e been positioned in the ,"T. -e ha e to take care to completely generate the left subtree of the root before generating the right subtree of the root. &f this is done, a simple recursi e procedure can be used to generate a balanced ,"T.

void balance( int sequence[], int first, int last) { int mid; if (first <= last) { mid = (first + last)/2; insert( sequence[mid], p); //p is t e pointer to t e tree balance(sequence, first, mid!"); balance(sequence, mid+", last); # #

Deleting a node from a "inary Search Tree:


Deletion of a node is not so straightforward as is the case of insertion. &t would depend on which particular node is being deleted. &n fact, we note that there can be three separate cases and each case needs to be handled somewhat differently. The arious cases are! *1+ deletion of a leaf node, *.+ deletion of an internal node with a single child (either a left or right subtree)3 *2+ deletion of an internal node with two children (ha1ing both left subtree an" right subtree. ) -eZll e%amine each case separately! a. Deletion of a leaf ode? "ince a leaf node has empty left and right subtrees, deleting a leaf node will render a tree with one less node but which remains a ,"T. This is illustrated below!

:0 b. Deletion of a ode &ith one child when the node gets deleted, the parent of the node must point to its left child or its right child. The parentZs reference to the node is reset to refer to the deleted nodeZs child. This has the effect of lifting up the deleted nodeZs children by one le el in the tree. An e%ample is shown below.

"ST after deletion

&t makes no difference if the node to be deleted has only a left or a right child.

The pre ious e%ample illustrated the case when the only child was a right child. The ne%t e%ample illustrates the case when the only child is a left child.

c. Deletion of a ode &ith t&o child nodes There is no one-step operation that can be performed since the parentZs right or left reference cannot refer to both the children at the same time. A deleted node with two children must be replaced by a alue which is one of! The largest alue in the deleted nodeZs left subtree. The smallest alue in the deleted nodeZs right subtree. This means that we need to be able to find, either the immediate predecessor or the immediate successor node to the node which is being deleted and replace the deleted node with this alue. The )eneral case of Deletion of a node ha2ing t&o child nodes. &n the following tree, we want to delete the node #. The node # has T1 as left subtree and

:@ T. as right subtree. Cote that all nodes of T1 are going to be smaller than nodes of T.. Cote further that the rightmost node of T1 will ha e the largest alue in that subtree. &t will be immediate predecessor of node #. All nodes in T. will be successor of this node.

&n order tra ersal! = D $ G [ _ B

<(T8-`

Cow let us say we want to delete node C. copy the immediate predecessor *the largest element from its left subtree+. &t would be B, the rightmost node of the left subtree. All elements in the left subtree are going to be smaller than this node. All elements in the right subtree are going to be greater than this node. B can simply replace C, while keeping the structure of the ,"T tree undisturbed. "o copy the node B at the node containing C.

:I

The node C can also be remo ed by replacing it with its immediate successor , the smallest node *left most node+ of the right subtree and making the appropriate links. &n this case node < becomes the right child of =

The subtree G becomes the left child of < and the subtree T becomes the right child of <. &n order tra ersal! = D $ G [ _ B < ( T 8 - `.

:N

$%ample 1! As an e%ample, consider the following ,"T and suppose that we are deleting the alue 1: from this tree.

5ind the immediate successor of 1: which is the leftmost node in its right subtree .@, and put this alue into the place currently occupied by 1:. delete the old copy of the node .@. The final tree is shown below.

::

$%ample .! Delete ode ( Code . is replaced with minimum alue in the right subtree i-e node 2. Code 2 is deleted from its current position

Code to delete a node from a "ST containing integer 2alues. 0t returns the tree after deleting the node &ith 2alue x: struct treenode *delete:tree "int x, struct treenode* /' { struct treenode *temp, *child$ if" / (( REVV ' else if" x < /!3data ' /* 0o left */ /!3left ( delete" x, /!3left '$ elseif" x 3 /!3data ' /* 0o ri $t */ /!3right ( delete" x, /!3right '$ else /* 8ound ele!ent to &e deleted */ //1eletin fro! an e!"t# su&tree

printf"A%lement not foundA'$

:; if" /!3left && /!3right ' /* '%o c$ildren */ { /* )e"lace %it$ s!allest in ri $t su&tree */ temp ( find:min" /!3right '$ /!3data ( tmp:cell!3data$ /!3right ( delete" /!3data, /!3right '$ ) else /* -ne c$ild */ { temp ( /$ if" /!3left (( REVV ' /* -nl# a ri $t c$ild */ child ( /!3right$ if" /!3right (( REVV ' /* -nl# a left c$ild */ child ( /!3left$ free" tmp:cell '$ return child$ ) return /$ )

;/

Aeight "alanced Trees (AI% Trees)


&f a ,"T is balanced, one can do insertion, search and deletion in )*log n+ time. ,ut if it is skewed, then these operations could take )*n+ time. Thus when n is large, it is always of interest to keep the tree balanced as far as possible. )ne of the first tree balancing algorithms was suggested by two (ussian scientists AdelZson-PelZskii and Bandis. "uch balanced trees are known by their initials as AI% trees. Definition *1+ A node of a tree is balance" if the heights of its children differ by one atmost. *.+ An A45 tree is a binary search tree in which all nodes are balanced. 5igure 1 shows two binary search trees1 the one on the left is APB, the one on the right is not.

5igure 1! APB and non-APB trees. o To maintain the APB property, the tree must be rebalanced, if necessary, e ery time a node is inserted or deleted. o The key to the rebalancing is a rotation operation, that grabs an unbalanced tree by its proper root node and redistributes its out-of-balance children. o 5or e%ample, suppose we ha e the following APB tree to which we add a node with alue c.

o The steps to add the node then rotate the tree into balance are the following!

;1

The height of a node is the longest path length. &n the following tree the heights of the nodes are indicated below! Codes 0/, N@, ;/ ! 6eight / Codes I/, :/ ! 6eight 1 Code N/ ! 6eight .. A new term is introduced now, called the ,alance factor. The "alance 1actor *,.5.+ of any node of a ,inary search tree, is the difference between the height of right child node *6(+ and the height of the left child node *6B+. ,.5. ? 6( Q 6B A 6eight balanced tree *an APB tree+, is one which is either empty, or each node of the tree has a balance factor of /, -1 or 1.

&f ,5 for any node is . or -. , we say that the tree is unbalanced. The tree can be balanced by appropriate rotation of sub trees around a particular node. &f the ,5 of all nodes remains /, -1 or1, after a new node is inserted in the tree, nothing needs to be done. 6owe er, if the tree gets unbalanced, we ha e to carry out rotation of subtrees. The rotation will depend on where the new node was inserted in the tree. After a node is inserted, we ha e to consider 0 separate cases of unbalancing . =ase 1! An insertion into the left subtree of the left child BB * single rotation right for balancing+ =ase .! An insertion into the right subtree of the left child (B * double rotation for balancing+ =ase 2! An insertion into the left subtree of the right child B( * double rotation for balancing+ =ase 0! An insertion into the right subtree of the right child (( * single rotation left for balancing+ '. Case %% ( ode added to %eft of %eft ): 6ere we consider the case where the tree gets unbalanced after a node is added to the left subtree of the left child. The node with ,5 . or -. must be brought down to a lower le el. )eneral case! consider the general BB case, where k1 and k. are nodes, and U , ` , a are sub trees. Bet us say insertion of a node in U causes the tree to be unbalanced.

;. The tree can be balanced by *right rotation+ mo ing k. down, and mo ing k1 up. The subtrees are taken care in the same way

(i) 0nsert at left of subtree ma9es tree unbalance (ii) After Single rotation right

,xample ': =onsider the following tree. &t is an APB tree, as each node has ,5 of /, -1, or 1.

Bet us now insert a new node : in this tree, which will be in the left subtree of left child*.@+ of the root *@I+.

,alance factor ,5 for 1. and .@ is -1, but for @I the ,5 is -.. "o the tree is unbalanced. The balance has been disturbed by insertion of a node in the left subtree of the left child .@. A right rotation of the tree around the node @I, causes node .@ to mo e up and @I to mo e down the tree. To maintain the ,inary search tree property, the right subtree of .@ needs to be attached to node @I. The tree is now balanced and is shown below.

;2

,xample (:

AI% property destroyed by insertion of < then fixed by a rotation

(. Case **( ode added *ight of *ight): )eneral case! consider the general (( case, where k1 and k. are nodes, and U , ` , a are sub trees. Bet us say insertion of a node in a causes the tree to be unbalanced. The tree can be balanced by *left rotation+ mo ing k 1 down, and mo ing k1 up. The subtrees are taken care in the same way

(i) 0nsert at right of right subtree ma9es tree unbalance (ii) After Single rotation left

This case is similar to BB case, e%cept that the tree gets unbalanced when a node is added to the *ight subtree of the *ight child of the root. =onsider the following tree which became unbalanced after insertion of node ;:. Code ;: was inserted in the right subtree of the right child :/.

;0

The tree can be balanced by a left rotation which causes node I/ to mo e down and node :/ to mo e up, as shown

+. Case *% (node added to *ight subtree of %eft child): Bet us now consider the general case, of a tree with nodes k1, k. and k2 with 0 sub trees A, ,, =, D. The tree gets unbalanced after insertion of a node in , or = . &t needs a double rotation to balance the tree. (otate k1 to the right and then k2 to the left

$%ample 1! &nserting 0@ to the tree makes the tree unbalanced at node @I.

;@

This is a case where the tree gets unbalanced after a node is added to the right subtree of the left child. Bet us check the balance factor in the following tree after node 0@ is attached to right subtree of the left node.@. 6ere node 1. has zero ,5, node .@ has ,5 of 1, and node @I has ,5 of -.. Cote that along that path, the ,alance 5actors are going as /, -1, ., that is, first decreasing and then increasing. &t needs a double rotation to balance the tree. A left rotation brings up the node 2: as shown below!

The tree is still unbalanced, but the nodes along the path to the root ha e the ,alance 5actors as -1, -1, and -. *the ,5 ha e the same sign+. This means a right rotation would be able to balance the tree, as it is similar to the BB case. The right rotation results in the following balanced tree!

.. Case %*: (%eft of *ight) This case is similar to the (B case. The tree gets unbalanced when a node is added to the %eft subtree of the *ight child. &t also needs a double rotation to balance the tree.

;I

The tree can be balanced by a double rotation. The final effect of the double rotation is shown below. Cote that in this case the node ( mo es up, with nodes < and O as its children and the subtrees are taken care of in the following way. Also note that the left to right ordering of subtrees T 1 T. T2 T0 is not disturbed by the balancing process.

=onsider the following tree which became unbalanced after inserting the node N@ in the left subtree of right child :/. 6ere node 0/ has zero ,5, node :/ has ,5 1, and node I/ has ,5 of -.. Cote that along that path, the ,alance 5actors are going as /, 1, -., that is, first increasing and then decreasing. The balance factor of I/ and :/ are of different signs.

The tree is balanced by mo ing N/ up .Code I/ retains its left subtree, and node :/ retains its right subtree. The left and right subtrees of the root node N/ are taken care of by nodes I/ and :/.

,xample +: Creating an AI% tree

( applying both single rotation and double rotation)

;N

"uppose we start with an initially empty A?2 tree and insert the keys 1 through N in se#uential order. The first problem occurs when it is time to insert 9ey +, because the A?2 property is iolated at the root. -e perform a single rotation %eft between the root and its right child to fi% the problem. The tree is shown in the following figure, before and after the rotation!

Ce%t, we insert the 9ey ., which causes no problems, but the insertion of @ creates a iolation at node 2, which is fi%ed by a single rotation %eft. ,esides the local change caused by the rotation, the programmer must remember that the rest of the tree must be informed of this change. 6ere, this means that .9s right child must be reset to point to 0 instead of 2. This is easy to forget to do and would destroy the tree *0 would be inaccessible+.

Ce%t, we insert J. This causes a balance problem for the root, since its left subtree is of height /, and its right subtree would be height .. Therefore, we perform a single rotation %eft at the root between . and 0. The rotation is performed by making . a child of 0 and making 09s original left subtree the new right subtree of .. $ ery key in this subtree must lie between . and 0, so this transformation makes sense.

The ne%t key we insert is N, which causes another rotation.

;:

"uppose we insert keys : through 1@ in re erse order. &nserting 1@ is easy, since it does not destroy the balance property, but inserting 10 causes a height imbalance at node N. &n our e%ample, the double rotation is a right#left double rotation and in ol es N, 1@, and 10. 6ere, k2 is the node with key N, k1 is the node with key 1@, and k. is the node with key 10. "ubtrees A, ,, =, and D are all empty.

)eneral case ( (*ight#left) double rotation)

Ce%t we insert 12, which re#uires a double rotation. 6ere the double rotation is again a right#left double rotation that will in ol e I, 10, and N and will restore the tree.

;; &n this case, k2 is the node with key I, k1 is the node with key 10, and k. is the node with key N. "ubtree A is the tree rooted at the node with key @, subtree , is the empty subtree that was originally the left child of the node with key N, subtree = is the tree rooted at the node with key 12, and finally, subtree D is the tree rooted at the node with key 1@.

&f 1. is now inserted, there is an imbalance at the root. "ince 1. is not between 0 and N, we know that the single rotation %eft will work.

&nsertion of 11 will re#uire a single rotation *ight !

To insert 1/, a single rotation needs to be performed, and the same is true for the subse#uent insertion of ;. -e insert : without a rotation, creating the almost perfectly balanced tree that follows.

1//

5inally, we insert :.@ to show the symmetric case of the double rotation. Cotice that :.@ causes the node containing ; to become unbalanced. "ince :.@ is between ; and : *which is ;9s child on the path to :.@ , a (*ight#left) double rotation needs to be performed, yielding the following tree.

)eneral case : (*ight#left) double rotation

+fter inserting ,-.


:.@

1/1

+fter balancing struct avl_node ! int element) struct avl_node *left) struct avl_node *right) int height) *) int height(struct avl_node * ) ! if( ## $%LL ) return &1) else return &>height) * Insertion into an AVL tree struct avl_node *insert( int /0 struct avl_node *1 ) ! return insert1( /0 10 $%LL )) *

struct avl_node * insert1( int /0 struct avl_node *10 struct avl_node * arent ) ! struct avl_node *rotated_tree) if( 1 ## $%LL ) ! 2* 3reate and return a one&node tree *2 1 # (struct avl_node *) malloc ( si4eof (struct avl_node) )) if( 1 ## $%LL )

1/. rintf(56ut of s ace"""5)) else ! 1&>element # /) 1&>height # 0) 1&>left # $%LL 1&>right # $%LL) * * else ! if( / < 1&>element ) ! 1&>left # insert1( /0 1&>left0 1 )) if( ( height( 1&'left ) & height( 1&'right ) ) ## 2) ! if( / < 1&>left&>element ) rotated_tree # s_rotate_left( 1 )) else rotated_tree # d_rotate_left( 1 )) if( arent&'left ## 1 ) arent&>left # rotated_tree) else arent&>right # rotated_tree) * else 1&>height # ma/( height(1&>left)0 height(1&>right) ) ( 1) * else 2* 78mmetric 3ase for right subtree *2) 2* 9lse / is in the tree alread8- :e;ll do nothing *2 * return 1) * Routine to perform single rotation 2* 1his function can be called onl8 if <2 has a left child- *2 2* Perform a rotate bet=een a node (<2) and its left child- *2 2* % date heights- *2 2* 1hen return ne= root- *2 struct avl_node *s_rotate_left(struct avl_node *k2 ) struct avl_node *k!" <1 # <2&>left) <2&>left # <1&>right) <1&>right # <2)

1/2 <2&>height # ma/( height(<2&>left)0 height(<2&>right) ) ( 1) <1&>height # ma/( height(<1&>left)0 <2&>height ) ( 1) return <1) 2* $e= root *2 * Routine to perform dou#le rotation 2* 1his function can be called onl8 if <3 has a left child *2 2* and <3;s left child has a right child *2 2* >o the left&right double rotation- % date heights *2 struct avl_node *d_rotate_left( avl_ tr <3 ) ! 2* rotate bet=een <1 and <2 *2 <3&>left # s_rotate_right( <3&>left )) 2* rotate bet=een <3 and <2 *2 return( s_rotate_left( <3 ) )) *

Time complexity of AI% tree operations A2erage Space Search 0nsert Delete $(n) $(log n) $(log n) $(log n) Korst case $(n) $(log n) $(log n) $(log n)

1/0

Splay Trees ' 3oti2ation ,inary search trees *,"T+ are meant to sol e dynamic dictionary problem. n keys are stored in such a way that each access'insert'delete operation costs O*log n+ time while still preser ing the properties of ,"T. ,alanced ,"Ts can achie e this goal but at a costbthey ha e to maintain e%tra Rbalance informationS. )n the other hand, splay trees can adGust the structure of itself effecti ely so that all standard search tree operations still can ha e an amortize" time bound of O*log n+. ,y amortized time, we mean the time per operation a eraged o er a worst-case se#uence of operations. "play trees are binary search trees which are self-adGusting in the following way! $ ery time we access a node of the tree, whether for retrie al or insertion or deletion, we perform radical surgery on the tree, resulting in the newly accessed node becoming the root of the modified tree. This surgery will ensure that nodes that are fre#uently accessed will ne er drift too far away from the root whereas inacti e nodes will get pushed away farther from the root.

Amortized comple%ity o "play trees can become highly unbalanced so that a single access to a node of the tree can be #uite e%pensi e. o 6owe er, o er a long se#uence of accesses, the few e%pensi e cases are a eraged in with many ine%pensi e cases to obtain good performance. Does not need heights or balance factors as in APB trees and colours as in (ed-,lack trees. The surgery on the tree is done using rotations, also called as splaying steps. There are si% different splaying steps. 1. aig (otation *(ight (otation+ .. aag (otation *Beft (otation+ 2. aig-aag *aig followed by aag+ 0. aag-aig *aag followed by aig+ @. aig-aig I. aag-aag =onsider the path going from the root down to the accessed node. $ach time we mo e left going down this path, we say we >>zig99 and each time we mo e right, we say we >>zag.99

0. Lig *otation and Lag *otation Cote that a zig rotation is the same as a right rotation whereas the zag step is the left rotation.

1/@

1igure ': aig rotation and zag rotation &&. aig-aag This is the same as a double rotation in an APB tree. Cote that the target element is lifted up by two le els.

1igure (: aig-zag rotation &&&. aag-aig This is also the same as a double rotation in an APB tree. 6ere again, the target element is lifted up by two le els.

1igure +: aag-zig rotation

1/I &P. aig-aig and aag-aag The target element is lifted up by two le els in each case. aig-aig is different from two successi e right rotations1 zag-zag is different from two successi e left rotations.

1igure .: aig-zig and zag-zag rotations

1igure 8: Two successi e right rotations

P.

"ee 5igure I for an e%ample of splaying

1/N

1igure J: An e%ample of splaying The abo e scheme of splaying is called bottom#up splaying. &n top#do&n splaying, we start from the root and as we locate the target element and mo e down, we splay as we go. This is more efficient. Search, Insert, Delete in Bottom-up Splaying Search *i, t+ &f item i is in tree t, return a pointer to the node containing i1 otherwise return a pointer to the null node.

"earch down the root of t, looking for i &f the search is successful and we reach a node + containing i, we complete the search by splaying at + and returning a pointer to + &f the search is unsuccessful, i.e., we reach the null node, we splay at the last non-null node reached during the search and return a pointer to null. &f the tree is empty, we omit any splaying operation.

$%ample of an unsuccessful search! "ee 5igure N

1/:

1igure M: An e%ample of searching in splay trees 0nsert *i, t+


"earch for i. &f the search is successful then splay at the node containing i. &f the search is unsuccessful, replace the pointer to null reached during the search by a pointer to a new node + to contain i and splay the tree at +

1igure F: An e%ample of an insert in a splay tree Delete *i, t+


"earch for i. &f the search is unsuccessful, splay at the last non-null node encountered during search. &f the search is successful, let + be the node containing i. Assume + is not the root and let y be the parent of +. (eplace + by an appropriate descendent of y in the usual fashion and then splay at y.

1/;

1igure B: An e%ample of a delete in a splay tree ,xample

1igure 'N. *esult of splaying at node '

11/

1igure ''. *esult of splaying at node ' a tree of all left children An access on the node with key . will bring nodes to within n'0 of the root 1igure '( *esult of splaying pre2ious tree at node (

1igure '+ *esult of splaying pre2ious tree at node +

1igure '. *esult of splaying pre2ious tree at node .

111

1igure '8 *esult of splaying pre2ious tree at node 8

1igure 'J *esult of splaying pre2ious tree at node J

1igure 'M *esult of splaying pre2ious tree at node M

11. 1igure 'F *esult of splaying pre2ious tree at node F

1igure 'B *esult of splaying pre2ious tree at node B

Creating a splay Tree: &nsert the elements 1 . 2 N @ ..@ 0nsert '? 1 0nsert (: 1 . 0nsert +: . 1 aag 2 1 0nsert M 2 . 1 1 N . Lag 2 N 2 . Lag . 1

112

0nsert 8 ( added as right of left tree )

aagaig (otation N @ 2 . 1 @ N

N 2 . 1 @ . 1 ( added as right of left tree ) @ 2 . 1


.. @

&nsert ..@

aagaig (otation @

N
.. @

N
.. @

@ N 2 1
.

.. @

@ 2 N

. 1 1

&nsert I
..@ .

LigLag @
.

..@

..@

@ 2 I N 1

I @ N

2 I

2 Lag

I ..@

N @

. 2 1

110

11@ "#Trees Definition ,-tree is a m-way search tree in which The root has at least one key Con-root nodes ha e at least m6. subtrees *i.e., at least *m - 1+6. keys+ All the empty subtrees *i.e., e%ternal nodes+ are at the same le el

,-trees are especially useful for trees stored on disks, since their height, and hence also the number of disk accesses, can be kept small. The growth and contraction of m-way search trees occur at the lea es. )n the other hand, ,-trees grow and contract at the root. 0nsertions &nsert the key to a leaf. ) erfilled nodes should send the middle key to their parent, and split into two at the location of the submitted key.

11I

Deletions
_ey that is to be remo ed from a node with non-empty subtrees is being replaced with the largest key of the left subtree or the smallest key in the right subtree. *The replacement is guaranteed to come from a leaf.+

11N

&f a node becomes under staffed, it looks for a sibling with an e%tra key. &f such a sibling e%ist, the node takes a key from the parent, and the parent gets the e%tra key from the sibling.

11:

11;

&f a node becomes under staffed, and it canZt recei e a key from a sibling, the node is merged with a sibling and a key from the parent is mo ed down to the node.

1./

1.1

1..

1.2

1.0

1.@

1.I

1.N

AASA0 )

1.:

1.;

12/

121

12.

122

120

"inary Aeaps
1A binary heap is a binary tree with the following properties 1. "tructure property A binary heap is a complete binary tree $ach le el is completely filled ,ottom le el may be partially filled from left to right 6eight of a complete binary tree with C elements is 5og.' .. 6eap-order property! The data item stored in each node is less than or e#ual to the data items stored in its children. Array implementation of heaps: Gi en element at position i in the array iZs left child is at position .i iZs right child is at position .iA1 iZs parent is at position

,inary heaps can either be a ma%imum heap or minimum heap. &n a ma%imum heap, e ery node inde%ed by i, other than the root, has AV<arent*i+W AViW. &n a minimum heap, e ery node inde%ed by i, other than the root, has AV<arent*i+W ! AViW.

Cote! This property makes a binary heap diffrent from a binary search tree. &n a binary tree, leftchil"! parent7rightchil". 6owe er, in a minimum heap, parent! leftchil" and parent! rightchil". "o a binary search tree can be iewed as sorted, while a heap cannot.

12@

"asic Aeap $perations:


'. 0nsertion: The new element to be inserted on the binary heap tree is placed ne%t to the last element of the array containing the heap . This is called the hole position. Ce%t it is mo ed up in the tree, to find its rightful place on the tree such that the heap order property is maintained. The reheap8p algorithm to do this is as follows! Percolate!p Algorithm for 3inAeap -hile *hole is not at the root and element E holeZs parent+ F Do e holeZs parent down Do e hole up H <lace element into final hole.

12I

Cow the hole is in proper place, as the hole alue is not less than the parent alue. The insertion algorithm terminates here. The final tree is shown below!

&t is easily seen that irrespecti e of the alue to be inserted, the ma%imum hole mo ement is limited to the height of the heap tree, and thus the insertion takes )*log C+ operations.

12N

$%ample .!

$%ample 2! =onstruct Da%-6eap

(. Creation: The binary heap tree can be created by inserting each element in an empty tree following the abo e algorithm. The time comple%ity of the operations for e ery node is bounded by )*log i+, which sums up to )* C+ for C elements. +. Deletion: &n a binary heap tree, we are not interested in remo ing a random element in the tree, but we want to delete the node with minimum alue which is sitting at the root. Deleting the root node from a tree ha ing C elements, lea es a hole at the root. Cow the tree must be readGusted by mo ing the hole down. This is done by <ercolateDown algorithm. DeleteHmin( ) <ut the last element in the root * That is 6 V1W ? 6 VC--W +1 <ercolateDown * 1 +1

12:

PercolateDo&n algorithm: As long as current size is not e%ceeded &f the hole is greater than its children, swap it with its smaller of the two children The worst case running time of deleteXmin is )*log C+ as the hole mo es from the root to its rightful place in the tree and this mo ement is limited by the height of the tree. $%ample 1! deletion in Da%-6eap

$%ample .! Deletion in Din-6eap

12;

10/

Printf ( ? Priorit8 @ueue em t8 ?))

101

8. "uilding a heap
struct heap:struct { /* 4aximum - that can fit in the heap */ int max:heap:siYe$ /* Surrent - of elements in the heap */ int siYe$ int *elements$ )$ typedef struct heap:struct *,RI1RI/W:TE%E%$ ,RI1RI/W:TE%E% create:pQ"int max:elements ' { ,RI1RI/W:TE%E% 2$ if" max:elements < 4IR:,T:.IP% ' printf"A,riority Queue siYe is too smallA'$

10.
2 ( ",RI1RI/W:TE%E%' malloc " siYeof "struct heap:struct' '$ if" 2 (( REVV ' printf"A1ut of spaceIIIA'$ /* 5llocate the array one extra for sentinel */

2!3elements ( "int *' malloc" " max:elements 9' * siYeof "int' '$ if" 2!3elements (( REVV ' printf"A1ut of spaceIIIA'$ 2!3max:heap:siYe ( max:elements$ 2!3siYe ( 8$ 2!3elements;8< ( 4IR:05/5$ return 2$ ) 1unction to perform insert in a binary heap /* 2!3element;8< is a sentinel */ Hoid insert" int x, ,RI1RI/W:TE%E% 2 ' { int i$ if" is:full" 2 ' ' printf"A,riority Queue is fullA'$ else { i ( 2!3siYe$ while" 2!3elements;i/>< 3 x ' { 2!3elements;i< ( 2!3elements;i/><$ i /( >$ ) 2!3elements;i< ( x$ ) )

1unction to perform deleteHmin in a binary heap Int { int i, child$ int min:element, last:element$ delete:min" ,RI1RI/W:TE%E% 2 '

102
if" is:empty" 2 ' ' { printf"A,riority Queue is emptyA'$ return 2!3elements;8<$ ) min:element ( 2!3elements;9<$ last:element ( 2!3elements;2!3siYe!!<$ for" i(9$ i*> <( 2!3siYe$ i(child ' { /* find smaller child */ child ( i*>$ if""child I( 2!3siYe' && "2!3elements;child 9< < 2!3elements;child<'' child $ /* percolate one level */ if" last:element 3 2!3elements;child< ' 2!3elements;i< ( 2!3elements;child<$ else brea#$ ) 2!3elements;i< ( last:element$ return min:element$ )

Aeap Practical ,xample : Priority :ueue Dany applications re#uire that we process records with keys'priorities in order, but not necessarily in full sorted order. *e.g. =<8 process scheduling+. &tems in a priority #ueue are not processed strictly in order of entry into the #ueue &tems can be placed on the #ueue at any time, but processing always takes the item with the largest key' priority Applications of priority ;ueues include: "imulation "ystems, where e ents need to be processed chronologically. [ob scheduling in computer systems.

"and&idth management

100 <riority #ueuing can be used to manage limited resources such as bandwidth on a transmission line from a network router. &n the e ent of outgoing traffic #ueuing due to insufficient bandwidth, all other #ueues can be halted to send the traffic from the highest priority #ueue upon arri al. This ensures that the prioritized traffic *such as real-time traffic, e.g. an (T< stream of a Po&< connection+ is forwarded with the least delay and the least likelihood of being reGected due to a #ueue reaching its ma%imum capacity. All other traffic can be handled when the highest priority #ueue is empty. Another approach used is to send disproportionately more traffic from higher priority #ueues. Dany modern protocols for Bocal Area Cetworks also include the concept of <riority Oueues at the Dedia Access =ontrol *DA=+ sub-layer to ensure that high-priority applications *such as Po&< or &<TP+ e%perience lower latency than other applications which can be ser ed with ,est effort ser ice. $%amples include &$$$ :/..11e *an amendment to &$$$ :/..11 which pro ides Ouality of "er ice+ and &T8-T G.hn *a standard for high-speed Bocal area network using e%isting home wiring *power lines, phone lines and coa%ial cables+. 8sually a limitation *policer+ is set to limit the bandwidth that traffic from the highest priority #ueue can take, in order to pre ent high priority packets from choking off all other traffic. This limit is usually ne er reached due to high le er control instances such as the =isco =allmanager, which can be programmed to inhibit calls which would e%ceed the programmed bandwidth limit.

Discrete e2ent simulation


Another use of a priority #ueue is to manage the e ents in a discrete e ent simulation. The e ents are added to the #ueue with their simulation time used as the priority. The e%ecution of the simulation proceeds by repeatedly pulling the top of the #ueue and e%ecuting the e ent thereon.

A5 and S3A5 search algorithms


The AJ search algorithm finds the shortest path between two ertices of a weighted graph, trying out the most promising routes first. The priority #ueue *also known as the fringe+ is used to keep track of une%plored routes1 the one for which a lower bound on the total path length is smallest is gi en highest priority. &f memory limitations make AJ impractical, the "DAJ algorithm can be used instead, with a double-ended priority #ueue to allow remo al of low-priority items.

*$A3 triangulation algorithm


The (eal-time )ptimally Adapting Deshes *()AD+ algorithm computes a dynamically changing triangulation of a terrain. &t works by splitting triangles where more detail is needed and merging them where less detail is needed. The algorithm assigns each triangle in the terrain a priority, usually related to the error decrease if that triangle would be split. The algorithm uses two priority #ueues, one for triangles that can be split and another for triangles that can be merged. &n each step the triangle from the split #ueue with the highest priority is split, or the triangle from the merge #ueue with the lowest priority is merged with its neighbours.

10@

%eftist Aeaps
he null path length of a binary tree is the shortest path from the root to a node without two children leftist heap is one in which! o both sub-trees are leftist heaps, and o the left sub-tree has a null path length greater than or e#ual to the that of the right sub-tree The definition suggests a bias to the left, howe er, this should not suggest that the tree is necessarily left-hea y The following are leftist trees *null path length in bold+!

As there is no relation between the nodes in the sub-trees of a heap!

10I o &f both the left and right sub-trees are leftist heaps but the root does not form a leftist -e only need to swap the two sub-trees o -e can use this to merge two leftist heaps heap,

-hen inserting a new node into a tree, a new one-node tree is created and merged into the e%isting tree. To delete a minimum item, we remo e the root and the left and right sub-trees are then merged. ,oth these operations take )*log n+ time. 5or insertions, this is slower than binary heaps which support insertion in amortized constant time, )*1+ and )*log n+ worst-case. Beftist trees are ad antageous because of their ability to merge #uickly, compared to binary heaps which take c*n+.

Derging Gi en two leftist heaps, recursi ely merge the larger alue with the right subheap of the root Tra ersing back to the root, swap trees to maintain the leftist heap property De#ueuing remo e the top node and merge the two sub-trees together

10N

10:

The heaps are merged, but the result is not a leftist heap as 2 is unhappy. -e must recurse to the root and swap sub-heaps where necessary. 5ind the unhappy nodes Q after updating the null path lengths.

10;

1@/

1@1

S9e& Aeap
"kew heap Q heap-ordered binary tree without a balancing condition. -ith these, there is no guarantee that the depth of the tree is logarithmic. &t supports all operations in logarithmic amortized time. &t is somewhat like a splay tree.

3erging
Dany operations with heap-ordered trees can be done using merging. 2nsert Q create a one-node tree containing + and merge that tree into the priority #ueue. 8in" minimum Q return the item at the root of the priority #ueue. %elete minimum Q delete the root and merge its left and right subtrees. %ecrease the 1alue of a no"e Q assume that p points to the node in the priority #ueue. Bower the alue of pZs key. Detach p from its parent, which yields two priority #ueues. Derge the two resulting priority #ueues. Thus, we need only see how merging priority #ueues is implemented.

Simplistic 3erging of Aeap#$rdered Trees


Assume we ha e two heap-ordered trees, )1 and ) , that need to be merged. &f either tree is empty, the other tree is the merged tree. )therwise, compare the roots. (ecursi ely merge the tree with the larger root into the right subtree of the tree with the smaller root.

1igure ' Simplistic merge of heap#ordered trees

The practical effect of the abo e operation is in fact an ordered arrangement consisting only of a single right path. Thus the operations can be linear.

The S9e& Aeap 4 A Simple 3odification


-e can make a simple modification to the merge operation and get better results. <rior to the completion of a merge, we swap the left and right children for e ery node in the resulting right path of the temporary tree.

1@.

1igure ( 3erging a s9e& heap

-hen a merge is performed in this way, the heap-ordered tree is also called a skew heap. BetZs consider this operation from a recursi e point of iew. Bet 5 be the tree with the smaller root and 9 be the other tree. &f one tree is empty, the other is the merged result. )therwise, let Temp be the right subtree of 5. Dake 5Zs left subtree its new right subtree. Dake the result of the recursi e merge of Temp and 93 the new left subtree of 5. The result of child swapping is that the length of the right path will not be unduly large all the time. The amortized time needed to merge two skew heaps is d*log n+.

1@2 $%ample!

1@0

"inomial :ueues
A binary heap pro ides )*log n+ inserts and )*log n+ deletes but suffers from )*n log n+ merges A binomial #ueue offers )*log n+ *a erage is constant time+ inserts and )*log n+ deletes and )*log n+ merges A Binomial Queue is a collection of heap#ordered trees known as a forest. $ach tree is a binomial tree. A recursi e definition is! 1. A binomial tree of height / is a one-node tree. .. A binomial tree, Bk, of height k is formed by attaching a binomial tree Bk 1 to the root of another binomial tree Bk1 .

1@@

1@I

1@N

1@: DATA S$*T0 ) The efficiency of handling data can be substantially impro ed if the data is sorted according to some criteria of order. &n a telephone directory we are able to locate a phone number, only because the names are alphabetically ordered. "ame thing holds true for listing of directories created by us on the computer. (etrie al of a data item would be ery time consuming if we donZt follow some order to store book inde%es, payrolls, bank accounts, customer records, items in entory records, especially when the number of records is pretty large. -e want to keep information in a sensible order. &t could be one of the following schemes! alphabetical order ascending'descending order order according to name, &D, year, department etc. The aim of sorting algorithms is to organize the a ailable information in an ordered form. There are dozens of sorting algorithms. The more popular ones are listed below! 1. 0nternal Sorting Selection Sort - 5ind the largest element in the array, and put it in the proper place. (epeat until array is sorted. This is also slow "ubble Sort - $%change two adGacent elements if they are out of order. (epeat until array is sorted. This is a slow algorithm. 0nsertion Sort - "can successi e elements for out of order item, then insert the item in the proper place. "ort small array fast, big array ery slowly. Shell Sort # "ort e ery Cth element in an array using insertion sort. (epeat using smaller C alues, until C ? 1. )n a erage, "hellsort is fourth place in speed. "hellsort may sort some distributions slowly. :uic9 Sort - <artition array into two segments. The first segment all elements are less than or e#ual to the pi ot alue. The second segment all elements are greater or e#ual to the pi ot alue. "ort the two segments recursi ely. Ouicksort is fastest on a erage, but sometimes unbalanced partitions can lead to ery slow sorting. 3erge Sort # "tart from two sorted runs of length 1, merge into a single run of twice the length. (epeat until a single sorted run is left. Dergesort needs C'. e%tra buffer. <erformance is second place on a erage, with #uite good speed on nearly sorted array. Dergesort is stable in that two elements that are e#ually ranked in the array will not ha e their relati e positions flipped. Aeap Sort 5orm a tree with parent of the tree being larger than its children. (emo e the parent from the tree successi ely. )n a erage, 6eapsort is third place in speed. 6eapsort does not need e%tra buffer, and performance is not sensiti e to initial distributions. .. ,xternal Sorting -e are interested in finding out as to which algorithms are best suited for a particular situation. The efficiency of a sorting algorithm can be worked out by counting the number of comparisons and the number of data mo ements in ol ed in each of the

1@; algorithms. The order of magnitude can ary depending on the initial ordering of data. 6ow much time does a computer spend on data ordering if the data is already orderedK -e often try to compute the data mo ements, and comparisons for the following three cases! - best case * often, data is already in order+, - worst case* sometimes, the data is in re erse order+, - a erage case* data in random order+. "ome sorting methods perform the same operations regardless of the initial ordering of data. -hy should we consider both comparisons and data mo ementsK &f simple keys are compared, such as integers or characters, then the comparisons are relati ely fast and ine%pensi e. &f strings or arrays of numbers are compared, then the cost of comparisons goes up substantially. &f on the other hand, the data items mo ed are large, such as structures, then the mo ement measure may stand out as the determining factor in efficiency considerations.

1I/

0nsertion Sort
The key idea is to pick up a data element and insert it into its proper place in the partial data considered so far. An outline of the algorithm is as follows! The list is di ided into two parts! sorted and unsorted. &n each pass, the first element of the unsorted part is picked up, transferred to the sorted sublist, and inserted at the appropriate place. A list of n elements will take at most n,- passes to sort the data.

0nsertion Sort ,xample

0nsertion Sort Algorithm /* Bith each pass, first element in unsorted sublist is inserted into sorted sublist. */ void insertion.ort"int a;<, int n' {

1I1 int i, temp, ]$ for "i ( 9$ i <( n $ i ' { temp ( a;i<$ for " ] ( i$ ] 3( 8 && temp<a;]<$ ]!!' { if" temp<a;]< ' a;]<( a; ]!9 <$ else brea#$ ) a;]< ( temp$ ) return$ > Algorithm Analysis: An ad antage of this method is that it sorts the array only when it is really necessary. &f the array is already in order, no mo es are performed. 6owe er, it o erlooks the fact that the elements may already be in their proper positions . -hen an item is to be inserted, all elements greater than this ha e to be mo ed. There may be large number of redundant mo es, as an element * properly located+ may be mo ed , but later brought back to its position. "est case! the data is already sorted. The inner loop is ne er e%ecuted, and the outer loop is e%ecuted nQ 1 times for total comple%ity of )*n+. Korst case: data in re erse order. The inner loop is e%ecuted the ma%imum number of times. Thus the comple%ity of the insertion sort in this worst possible case is #uadratic or )*n.+.

1I.

3ergesort
The mergesort,sorting algorithm uses the di ide and con#uer strategy of sol ing problems in which the original problem is split into two problems, with size about half the size of the original problem. The basic idea is as follows. "uppose you ha e got a large number of integers to sort. -rite each integer on a separate slip of paper. Dake two piles of the slips. "o the original problem has been reduced to sorting indi idually two piles of smaller size. Cow reduce each pile to half of the e%isting size. There would be now 0 piles with a smaller set of integers to sort. _eep on increasing the number of piles by reducing their lengths by half e ery time. =ontinue with the process till you ha e got piles with ma%imum two slips in each pile. "ort the slips with smaller number on the top. Cow take adGacent piles and merge them such that resulting pile is in sorted form. The piles would keep growing in size but now this time these are in sorted order. "top when all piles ha e been taken care of and there remains one single pile. Thus the mergesort can be thought of as a recursi e process. Bet us assume that the elements are stored in an array. 3ergesort Algorithm: '. Di2ide Step &f gi en array A has zero or one element, return #1 it is already sorted. )therwise, di ide A into two arrays, A1 and A., each containing about half of the elements of A. (. *ecursion Step (ecursi ely sort array A1 and A.. +. Con;uer Step =ombine the elements back in A by merging the sorted arrays A1 and A. into a sorted se#uence. Khat &ould be the complexity of the processO "ince this algorithm uses the di ide and con#uer strategy and employs the hal ing principle, the sorting process would ha e )*log . n+ comple%ity. 6owe er, the merging operation would in ol e mo ement of all the n elements *linear time +, and we shall show later that the o erall comple%ity turns out to be )*C log. C+. -e can merge two input arrays A and , to result in a third array =. Bet the inde% counter for the respecti e arrays be actr, bctr, and cctr. The inde% counters are initially set to the position of the first element. The smaller of the two elements AVactrW and ,VbctrW is stored in =VcctrW as shown below! if AVactrW E ,VbctrW F =VcctrW ? AVactrW1 cctrAA1 actrAA1 H else F

1I2 =VcctrW ? ,VbctrW1 cctrAA1 bctrAA1 * Bet us take an e%ample. "ay at some point in the sorting process we ha e to merge two lists 1, 2, 0, N and ., @, ;, 11 . -e store the first list in Array A and the second list in Array ,. The merging goes in following fashion! -e store the first list in Array A and the second list in Array ,. The merging goes in following fashion!

:+ample& Binear Derge A


1 2 0 N

,
. @ ; 11

actr
1 2 0 N

bctr
. @ ; 11

cctr
1

. @

; 11

. @

; 11

. @

; 11

0 N

. @

; 11

@ ; 11

0 N

@ ; 11

0 N

. @ ; 11

11

1I0 The array is recursi ely split into two hal es and mergesort function is applied on the two arrays separately. The arrays get sorted. Then these two arrays are merged. The mergesort and merge functions are shown below! -include<stdio.h3 void merge " int a ;<, int a9;<, int n9,int a>;<, int n>' { int ], p(8, p9(8,p>(8$ while " p9 < n9 && p> < n> ' { if" a9;p9< < a>;p> <' array ;p < ( a9;p9 <$ else a;p < ( a>;p> <$ ) while " p9 < n9 ' array ;p < ( a9;p9 <$ while " p> < n> ' a;p < ( a>;p> <$ ) void mergesort"int a;98<, int n' { int ],n9,n>,a9;98<,a>;98<$ if "n39' { n9(n/>$ n> ( n ! n9$ for " ] ( 8$ ]<n9$ ] ' a9;]<( a;]<$ for " ] ( 8$ ]<n>$ ] ' a>;]<( a;] n9<$ mergesort"arr9, n9'$ mergesort"arr>, n>'$ merge"array, arr9, n9, arr>, n>'$ ) ) main"' { int i,],#,n,tmp,a;98<$ clrscr"'$ scanf"ADdA,&n'$ for"i(8$i<n$i '

1I@ scanf"ADdA,&a;i<'$ mergesort"a,n'$ printf"Asorted listCnA'$ for"i(8$i<n$i ' printf"ADdCnA,a;i<'$ getch"'$ ) 4odel outout= +fter merging A31 B CAD. B +fter merging A2D B C A1. B merged arra8 is A31 D. B merged arra8 is A1. 2D B merged arra8 is A1. 2D 31 D. B

+fter merging A31 D. B C A1. 2D B +fter merging A23 B C AE2 B +fter merging A30 B C AFF B

merged arra8 is A23 E2 B merged arra8 is A30 FF B merged arra8 is A23 30 FF E2 B

+fter merging A23 E2 B C A30 FF B

+fter merging A1. 2D 31 D. B C A23 30 FF E2 B merged arra8 is A1. 23 2D 30 31 D. FF E2 B To sort an array A of size n, the call from the main program would be mergesort(A< n). 6ere is a typical run of the algorithm, for an array of size :. 8nsorted array A ? V21 0@ .0 1@ .2 ;. 2/ NN W The original array is kept on splitting in two hal es till it reduces to array of one element. Then these are merged. V21 0@ .0 1@ .2 ;. 2/ NN W V21 0@ .0 1@W A31 D. B 31 D. A31 D. B A1. 2D 31 D. B A.0 1@W 2D A1. 2D B 1. A1. 23 2D 30 31 D. FF E2 B V.2 ;. 2/ NN W V.2 ;.W 23 A23 30 FF E2 B V2/ NN W 30 V2/ NN W FF

V.2 ;. W E2

1II Computational Complexity: &ntuiti ely we can see that as the mergesort routine reduces the problem to half its size e ery time, *done twice+, it can be iewed as creating a tree of calls, where each le el of recursion is a le el in the tree. $ffecti ely, all n elements are processed by the merge routine the same number of times as there are le els in the recursion tree. "ince the number of elements is di ided in half each time, the tree is a balanced binary tee. The height of such a tree tends to be log n. The merge routine steps along the elements in both hal es, comparing the elements. 5or n elements, this operation performs n assignments, using at most n Q 1 comparisons, and hence it is )*n+. "o we may conclude that V log n . )*n+ W time merges are performed by the algorithm. The same conclusion can be drawn more formally using the method of recurrence relations. Bet us assume that n is a power of ., so that we always split into e en hal es. The time to mergesort n numbers is e#ual to the time to do two recursi e mergesorts of size n'., plus the time to merge, which is linear. 5or n ? 1 , the time to mergesort is constant. -e can e%press the number of operations in ol ed using the following recurrence relations! T*1+ ? 1 T*n+ ? . T*n'.+ A n 8sing same logic and going further down T*n'.+ ? . T*n'0+ A n'. "ubstituting for T*n'.+ in the e#uation for T*n+,we get T*n+ ? .V . T*n'0+ A n'. W A n ? 0 T*n'0+ A .n Again by rewriting T*n'0+ in terms of T*n':+, we ha e T*n+ ? 0 V . T*n':+ A n'0 W A .n ? : T*n':+ A 2 n ? .2 T* n' .2 + A 2 n The ne%t substitution would lead us to T*n+ ? .0 T*n' .0 + A 0 n

1IN

=ontinuing in this manner, we can write for any k, T*n+ ? .k T*n' .k + A k n This should be alid for any alue of k. "uppose we choose k ? log n, i.e. . k ? n. Then we get a ery neat solution! T*n+ ? n T*1+ A n log n ? n log n A n Thus T*n+ ? )* n log n+ This analysis can be refined to handle cases when n is not a power of .. The answer turns out to be almost identical. Although mergesortZs running time is ery attracti e, it is not preferred for sorting data in main memory. The main problem is that merging two sorted lists uses linear e%tra memory * as you need to copy the original array into two arrays of half the size+, and the additional work spent copying to the temporary array and back, throughout the algorithm, has the effect of slowing down the sort considerably. The copying can be a oided by Gudiciously switching the roles of list and temp arrays at alternate le els of the recursion. 5or serious internal sorting applications, the algorithm of choice is the Ouicksort, which we shall be studying ne%t.

1I: :uic9sort As the name implies the #uicksort is the fastest known sorting algorithm in practice. &t has the best a erage time performance. Bike merge sort, Ouicksort is also based on the "i1i"e,an",con$uer paradigm. ,ut it uses this techni#ue in a somewhat opposite manner, as all the hard work is done before the recursi e calls. &t works by partitioning an array into two parts, then sorting the parts independently, and finally combining the sorted subse#uences by a simple concatenation.

&n particular, the #uick-sort algorithm consists of the following three steps! 1. &hoosing a pi$ot:!. To partition the list, we first choose some element from the list which is e%pected to di ide the list e enly in two sublists. This element is called a pi$ot. .. Partitioning: Then we partition the elements so that all those with alues less than the pi ot are placed in one sublist and all those with greater alues are placed in the other sublist. '( Rec%r! (ecursi ely sort the sublists separately. (epeat the partition process for both the sublists. =hoose again two pi ots for the two sublists and make 0 sublists now. _eep on partitioning till there are only one cell arrays that do not need to be sorted at all. ,y di iding the task of sorting a large array into two simpler tasks and then di iding those tasks into e en simpler task, it turns out that in the process of getting prepared to sort , the data ha e already been sorted. This is the core part of the #uicksort. The steps in ol ed in the #uicksort algorithm are e%plained through an e%ample. $%ample array! V @I .@ lh 2N @: ;@ 1; N2 2/ W rh

1. =hoose first element @I as pi ot. .. Do e rh inde% to left until it coincides with lh or points to alue smaller than pi ot. &n this e%ample it already points to alue smaller than the pi ot. 2. Do e lh inde% to right until it coincides with rh or points to alue e#ual to or greater than pi ot. V @I .@ 2N @: lh ;@ 1; N2 2/ W rh

1I;

0. &f lh and rh not pointing to same element , e%change the elements. V@I .@ 2N 2/ lh ;@ 1; N2 @:W rh

@. (epeat steps . to 0 until lh and rh coincide. V@I .@ 2N 2/ lh ;@ 1; rh N2 @:W

mo e lh to right till it finds an element larger than @I V@I .@ 2N 2/ ;@ lh 1; rh N2 @:W

Cow e%change V@I .@ 2N 2/ 1; lh ;@ rh N2 @:W

mo e rh to left V@I 1; ;@ N2 @:W lh rh Co e%change now, as both lh and rh point to the same element I. V1; This will be the smallest alue. $%change this with the pi ot. .@ 2N 2/ @I ;@ N2 @:W .@ 2N 2/

N. This will result in two sub arrays, one to left of pi ot and one to right of pi ot. P'B (8 +M +N Q ;< P B8 M+ 8F Q

:. (epeat steps 1 to I for the two sub arrays recursi ely.

1N/

0mplementation of :uic9sort:
Quic#sort" int a;<, int low, int high ' { int pivot$ /* /ermination conditionI */ if " low<hign ' { pivot ( partition" a, low, high '$ Quic#sort" a, low, pivot!9 '$ Quic#sort" a, pivot 9, high '$ ) ) int partition" int a;<, int low, int high ' { int left, right,temp$ int pivot:item$ pivot:item ( a;low<$ pivot ( low$ left (low 9$ right ( high$ while " left < right ' { /* 4ove left while item < pivot */ while" a;left< <( pivot:item ' left $ /* 4ove right while item 3 pivot */ while" a;right< 3( pivot:item ' right!!$ if " left < right ' { temp ( a;left<$ a;left<(a;right<$ a;right<(temp$ )

1N1
) /* right is final position for the pivot */ a;low< ( a;right<$ a;right< ( pivot:item$ return right$

$%ercise! sort the following numbers .2, 1., 1@, 2:, 0.,1:,2I,.;,.N Pic9ing the Pi2ot:

first element ba if input is sorte or in reverse sorte or er ba if input is nearly sorte variation! particular element "e#g# mi le element$

ran om element even a malicious agent cannot arrange a ba input me ian of three elements choose the me ian of the left, right, an center elements

Analysis of :uic9sort: To do the analysis let us use the recurrence type relation used for analyzing mergesort. -e can drop the steps in ol ed in finding the pi ot as it in ol es only constant time. -e can take T*/+ ? T*1+ ? 1. The running time of #uicksort is e#ual to the running time of the two recursi e calls, plus the linear time spent in the partition. This gi es the basic #uicksort relation T*C+ the time for Ouicksort on array of C elements, can be gi en by T*C+ ? T*G + A T* C Q G Q 1 + A C, -here G is the number of elements in the first sublist. "est case analysis: The best case analysis assumes that the pi ot is always in the middle. To simplify the math, we assume that the two sublists are each e%actly half the size of the original. Then we can follow the same analysis as in merge sort and can show that T*C+ ? T*C'.+ A T*C'.+ A 1 leads to T*C+ ? )* C log C +

1N. Korst Case Analysis! The partitions are ery lopsided, meaning that either left partition eBe ? / or C Q 1 or right partition e(e ? C Q 1 or /, at each recursi e step. "uppose that Beft contains no elements, (ight contains all of the elements e%cept the pi ot element *this means that the pi ot element is always chosen to be the smallest element in the partition+, 1 time unit is re#uired to sort / or 1 elements, and C time units are re#uired to partition a set containing C elements. Then if C M 1 we ha e! T*C+ ? T*C-1+ A C This means that the time re#uired to #uicksort C elements is e#ual to the time re#uired to recursi ely sort the C-1 elements in the (ight subset plus the time re#uired to partition the C elements. ,y telescoping the abo e e#uation we ha e! T*C+ ? T*C-1+ A C T*C-1+ ? T*C-.+ A *C-1+ T*C-.+ ? T*C-2+ A *C-.+ L.. T*.+ ? T*1+ A . T*C+ ? T*1+ A . A 2 A 0 A L A C ? C*CA1+'. ? )*C.+ This implies that whene er a wrong pi ot is selected it leads to unbalanced partitioning.

1N2

Aeap Sort
The heap sort is the slowest of the O*n log n+ sorting algorithms, but unlike the merge and #uick sorts it doesn9t re#uire massi e recursion or multiple arrays to work. This makes it the most attracti e option for 1ery large data sets of millions of items. Algorithm! 1. building a heap out of the data set, .. remo ing the largest item and placing it at the end of the sorted array 2. After remo ing the largest item, reconstruct the heap and remo es the largest remaining item and places it in the ne%t open position from the end of the sorted array. 0. steps .f2 repeated until there are no items left in the heap and the sorted array is full. $lementary implementations re#uire two arrays - one to hold the heap and the other to hold the sorted elements. To do an in-place sort and sa e the space the second array would re#uire, the algorithm below 4cheats4 by using the same array to store both the heap and the sorted array. -hene er an item is remo ed from the heap, it frees up a space at the end of the array that the remo ed item can be placed in. Pros: &n-place and non-recursi e, making it a good choice for e%tremely large data sets. Cons: "lower than the merge and #uick sorts. As mentioned abo e, the heap sort is slower than the merge and #uick sorts but doesn9t use multiple arrays or massi e recursion like they do. This makes it a good choice for really large sets, but most modern computers ha e enough memory and processing power to handle the faster sorts unless o er a million items are being sorted. The 4million item rule4 is Gust a rule of thumb for common applications - high-end ser ers and workstations can probably safely handle sorting tens of millions of items with the #uick or merge sorts. 6eap sort ! The siftDown*+ function builds and reconstructs the heap. 2oid heap"ort*int numbersVW, int arrayXsize+ F int i, temp1 for *i ? *arrayXsize ' .+-11 i M? /1 i--+ siftDown*numbers, i, arrayXsize+1 for *i ? arrayXsize-11 i M? 11 i--+ F temp ? numbersV/W1 numbersV/W ? numbersViW1 numbersViW ? temp1 siftDown*numbers, /, i-1+1

1N0 H H 2oid siftDown*int numbersVW, int root, int bottom+ F int done, ma%=hild, temp1 done ? /1 &hile **rootJ. E? bottom+ ff *3done++ F if *rootJ. ?? bottom+ ma%=hild ? root J .1 else if *numbersVroot J .W M numbersVroot J . A 1W+ ma%=hild ? root J .1 else ma%=hild ? root J . A 11 if *numbersVrootW E numbersVma%=hildW+ F temp ? numbersVrootW1 numbersVrootW ? numbersVma%=hildW1 numbersVma%=hildW ? temp1 root ? ma%=hild1 H else done ? 11 H H Running time analysis: 1. &uilding a heap tree of ' elements ( o repeatedly insert ' elements ( )$'log'% time 2. *erform ' delete+a, operation ( each delete+a, operation requires )$log'% time ( to delete ' elemens - )$'log'% 3. .ecord these elements in a second array and copy it back ( )$'% otal time comple,ity - )$'log'%

1N@ SA,%% S$*T

G 1his sort algorithm is also called diminishing increment sort- +ctuall8 this naming is more meaningful than 7hell 7orting +lgorithm G 1he algorithm sorts the sub&list of the original list based on increment value or seHuence number < G 3ommon 7eHuence numbers are .0301- 1here is no roof that these are the best seHuence numbersG 9ach sub&list contains ever8 <th element of the original list

>efinition
G G Ior e/am le: if < # . then sub&lists =ill be as follo=ssA0B sA.B sA10B --- 1his means that there are . sub&lists and each contain 12. of the original list7ublist1: 7ublist2: 7ublist3: 7ublistD: 7ublist.: sA0B sA1B sA2B sA3B sADB sA.B sAJB sAFB sA,B sAEB sA10B sA11B sA12B sA13B sA1DB -----------

Kf < # 3 then there =ill be three sub&lists and so on-

1NI

7hell 7ort Process


G 3reate the sub&lists based on increment number (7eHuence number) G 7ort the lists G 3ombine the lists Lets see this algorithm in action

7hell 7ort Process


G LetLs sort the follo=ing list given the seHuence numbers are .0 30 1 30 J2 .3 D2 1F EF E1 3,

1NN

7hell 7ort Process <#.


30 62 53 42 17 97 91 38
Step ': Create the sub list 9 = 8 "V/W "V@W "V1W "VIW "V.W "VNW "V2W "V0W

2/ I. @2 0. 1N ;N ;1 2:
V/W V1W V.W V2W V0W V@W VIW VNW

Step ( # +: Sort the sub list R combine "V/W E "V@W This is )_ "V1W E "VIW This is )_ "V.W C "VNW This is not )_. "wap them

2/ I. 2: @2 0. 1N ;N ;1 @2 2:
V/W V1W V.W V2W V0W V@W VIW VNW

7hell 7ort Process <#3


30 62 53 42 17 97 91 38
Step ': Create the sub list 9 = + "V/W "V2W "VIW "V1W "V0W "VNW "V.W "V@W Step ( # +: Sort the sub list R combine "V/W "V2W "VIW "V1W "V0W "VNW ")(T them "V.W "V@W +N< .(< B' $/ J(< 'M< 8+ not $/ 'M< 8+< J( +F< BM $/

2/ I. 2: 0. 1N ;N ;1 @2
V/W V1W V.W V2W V0W V@W VIW VNW

2/ 1N I. 2: 0. @2 1N ;N ;1 I. @2
V/W V1W V.W V2W V0W V@W VIW VNW

1N:

7hell 7ort Process <#1


30 62 53 42 17 97 91 38
Step ': Create the sub list 9 =' "V/W "V1W "V.W "V2W "V0W "V@W "VIW "VNW

2/ 1N 2: 0. @2 ;N ;1 I.
V/W Step ( # +: Sort the sub list R combine "orting will be like insertion sort V1W V.W V2W V0W V@W VIW VNW

2/ 2/ 1N 1N 2: 0. @2 I. ;N ;1 ;N I.
V/W V1W V.W V2W V0W V@W VIW VNW

D)C$

7hellsort +nal8sis
G 1he running time of 7hellsort de ends heavil8 on the choice of increment seHuencesG 7hell suggested starting ga at $22 and halving it until reaches 1G 7hellsort des ite of three nested loo 0 re resents a substantial im rovement over the insertion sort

1N;

7hellsort +nal8sis
G :hen 7hellLs increment are used0 the =orst case can be 6($2)G :hen $ is an e/act o=er of t=o one can rove that the average running time is 6($322)G + minor change to the increment seHuence can im rove the Huadratic =orst case from occurring-and it becomes even0 then =e can add one to ma<e it odd- :e can then rove that the =orst case is not Huadratic but onl8 6($322)(ef! Dark Allan -iess

"hell sort is a relati ely fast algorithm and is easy to code. &t attempts to roughly sort the data first, mo ing large elements towards one end and small elements towards the other. &t performs se eral passes o er the data, each finer than the last. After the final pass, the data is fully sorted. "hell sort #uickly arranges data by sorting e ery nth element, where n can be any number less than half the number of "ata. )nce the initial sort is performed, n is reduced, and the data is sorted again until n e#uals 1. &t is ital that the data is finally sorted with n ? 1, otherwise there may be out-of-order elements remaining.

Selecting good 2alues for n


=hoosing n is not as difficult as it might seem. The only se#uence you ha e to a oid is one constructed with the powers of .. Do not choose *for e%ample+ 1I as your first n, and then keep di iding by . until you reach 1. &t has been mathematically pro en that using only numbers from the power series F1, ., 0, :, 1I, 2., ...H produces the worst sorting times. The fastest times are *on a erage+ obtained by choosing an initial n somewhere close to the ma%imum allowed and continually di iding by ... until you reach 1 or less. (emember to always sort the data with n ? 1 as the last step. 1unction for Shell sort: -include<stdio.h3 -include<conio.h3

1:/ main"' { int i,],#,tmp,a;98<$ clrscr"'$ scanf"ADdA,&n'$ for"i(8$i<n$i ' scanf"ADdA,&a;i<'$ for"#(n/>$#38$#/(>' for"i(#$i<n$i ' { tmp(a;i<$ for"](i$]3(#$](]!#' { if"tmp<a;]!#<' a;]<(a;]!#<$ else brea#$ ) a;]<(tmp$ ) printf"Asorted listCnA'$ for"i(8$i<Z$i ' printf"ADdCnA,a;i<'$ getch"'$ ) ,xample: The data in the table needs to be sorted into ascending order. 5or simplicity, we ha e chosen the se#uence F2, ., 1H for our n. The top line of each table shows the data before we performed that step, the bottom shows the data afterwards. &n this e%ample, we will assume there is a selection sort being used to do the actual sorting. : 0 1 @ N I ; 2 .

The unsorted data

1. As mentioned abo e, we will be using an initial alue of 2 for n. This is less than the ma%imum *which in this case is 0, because this is the largest number less than half the number of elements we ha e+. -e pretend that the only elements in the data set are elements containing @, : and ; *highlighted in bold+. Cotice that this is e ery 2rd element * n is 2+. After sorting these, we look at the elements to the right of the ones we Gust looked at. (epeat the sort and shift routine until all of the elements ha e been looked at once. "o if

1:1 n ? 2, you will need to repeat this step 2 times to sort e ery element. Cote that only the highlighted elements are e er changed1 the ones with a white background are totally ignored.

F 8

0 0

1 1

8 F

N N

I I

B B

2 2

. .

<ut the :, @ and ; into ascending order *ignoring the other elements+

@ @

. +
2 2

1 1

: :

M .
0 0

I I

; ;

+ M
N N

. .

Do the same for 0, N and 2 @ @

' '

: :

J (

; ;

( J

As well as 1, I and ....

.. Cow that all of the elements ha e been sorted once with n ? 2, we repeat the process with the ne%t alue of n *.+. &f you look carefully, there is a general congregation of large numbers at the right hand side, and the smaller numbers are at the left. There are still #uite a few misplaced numbers *most notably :, ., @ and I+, but it is better sorted than it was.

8 '

2 2

' .

: :

. 8

. .

B J

N N

J B

<lace the odd elements into ascending order

1 1

+ (

0 0

F +

@ @

( M

I I

M F

; ;

And the same for the e en elements...

1:. 2. `ou can see now that the data is almost completely sorted - after Gust . more steps3 All that remains is to sort it again with n ? 1 to fi% up any elements that are still out of order. -hen n ? 1, we are Gust performing a normal sort, making sure e1ery element in the dataset is in its correct place. `ou may wonder why don9t we Gust skip to this step. `es, doing that would work, howe er the selection and bubble sorts are fastest when the data is already sorted *or close to+. The shell sort method orders the data in fewer steps than would be re#uired for either of the abo e methods.

1 1

. .

0 2

2 0

@ @

N I

I N

: :

; ;

The few elements which are still out of order are fi%ed. 1 . 2 0 @ I N : ;

All sorted3

1:2

1:0

1:@

9/ternal 7orting
Performing sorting o erations on amounts of data that are too large to fit into main memor8-

*eplacement Selection
1. =hoose as large a priority #ueue as possible, say of D elements .. "ort "tep o &nitialization "tep! (ead D records into the priority #ueue o (eplacement "tep *creating a single run+! 1. Delete the smallest record from the priority #ueue and write it out .. (ead a record from the input file. &f the new element is smaller than the last one output, it cannot become part of the current run. Dark it as belonging to the ne%t run and treat it as greater than all the unmarked elements in the #ueue. 2. Terminate the run when a marked element reaches the top of the #ueue 2. Derge "tep! "ame as before

Você também pode gostar