You are on page 1of 24

BIRLAINSTITUTEOFTECHNOLOGYANDSCIENCEPILANI

K.K.BIRLAGOACAMPUS
SecondSemester20152016
LabSheet10

Topicscovered:
Unions
Enums
Recursion
SelfreferentialstructuresArecap
Dynamicmemoryallocation
Linkedlists

1. Unions
1.1. Introduction
A
union can be pictured as a chunk of memory that can be interpreted as variable of
different data types. Once a new value is assigned to a field, the existing data is
overwritten with the new data. The memory area storing the value has no intrinsic type
(other than just bytes or words of memory), but the value can be treated as one of
severaldatatypes,havingthetypeofthevaluethatwaslastwrittentothememoryarea.

1.2. Awordaboutunions
Unions are known as the variant part of variant records in many other languages. They
have a similar appearance to structs, but the memory layout has one crucialdifference.
Instead of each member being storedaftertheendofthepreviousone,allthemembers
haveanoffsetofzero.
The storage for the individual members is thus overlaid: only onememberatatimecan
bestoredthere .Aunionhasthefollowinggeneralform:

unionoptional_tag{
type_1identifier_1
type_2identifier_2
...
type_Nidentifier_N
}optional_variable_definitions

1.3. AnExample
Since all variables in a union share the address space, you can imagine the
consequenceifwetrytoprintthevaluesoftheunionvariables.
Consider the example below. Both
x and y share thesamelocation.Ifwechange
x
,we
canseethechangesbeingreflectedin y
.

#include<stdio.h>
uniontest{
intx,y
}
intmain(){
uniontestt
t.x=2
printf("Aftermakingx=2:\nx=%d,y=%d\n\n",t.x,t.y)
t.y=10
printf("Aftermakingy=10:\nx=%d,y=%d\n\n",t.x,t.y)
return0
}

1.4. Differencebetweenunionandstructure
Though unions are similar to structure in so many ways,thedifferencebetweenthemis
crucialtounderstand.Thiscanbedemonstratedbythisexample:

#include<stdio.h>
unionjob{
charname[32]
floatsalary
intworker_no
}u //uisavariableofunion
job
structjob1{
charname[32]
floatsalary
intworker_no
}s //sisavariableofstructurejob1

intmain(){
printf("sizeofunion=%lu\n",sizeof(u))
printf("sizeofstructure=%lu\n",sizeof(s))
return0
}

As you will see on executing this code that there is difference in memory allocation
between union and structure. The amount of memory required to store a structure
variableisthesumofmemoryrequiredbyallthemembersofstructure.


But, the memory required to store a union variable is the memory required for largest
elementofanunion.



Whatdifferencedoesitmakebetweenstructureandunion?
As you know, all members of structure can be accessed at any time. But, only one
member of union can be accessed at a time and other members will contain garbage
value.

#include<stdio.h>
unionjob{
charname[32]
floatsalary
intworker_no
}u

intmain(){
printf("Entername:\n")
scanf("%s",u.name)
printf("Name:%s\n",u.name)
printf("Salary:%.1f\n",u.salary)
printf("Entersalary:\n")
scanf("%f",&u.salary)
printf("Name:%s\n",u.name)
printf("Salary:%.1f\n",u.salary)
return0
}

Note: Youwillgetagarbagevalueofsalaryforthefirstprintf.

Whythisoutput?
Initially, the name input from the user will be stored in
u.name and other members of
union will contain garbage value. But when user enters value of salary, then that value
will be stored in
u.salary and other members will contain garbagevalue.Thusin output,
salaryisprintedaccuratelybut,namedisplayssomerandomstring.

1.5. PassingUnionToaFunction
Union can be passed to a function in similar manner as structures (refertopreviouslab
sheet).

2. Enums
2.1. Introduction
Enums (enumerated types) are simply a way of associating a series of names with a
seriesofintegervalues.Thegeneralformofanenumisasfollows:

enumoptional_tag{stuff...}optional_variable_definitions

The stuff... in this case is a list of identifiers, possibly with integer values assigned to
them. Twoenumnames(members)canhavesamevalue.Anenumeratedtypeexample
is:

enumsizes{small=7,medium,large=10,humongous}

The integervaluesstartat
zerobydefault.Ifyouassignavalueinthelist,thenextvalue
isonegreater,andsoon.

Enum enhance the readability of the code. Also, long lists of constants get mapped to
integer values automatically provided a starting value. These values canbecustomized
whererequired.Automaticvalueassignmentpreventsconflictinvalues.

2.2. AnExample
Checktheoutputofthefollowingprogram:

#include<stdio.h>

enumday{sunday=1,monday,tuesday,wednesday,thursday,friday,saturday}

intmain(){
enumdayd=thursday
printf("Thedaynumberstoredindis%d\n",d)
return0
}

Note: Trychangingthevalue assignedtosundayandchecktheresult.Alsotrytoassign
samevaluetodifferentdaysandchecktheresult.

So, Enums in C are numbers that have convenient names inside your code. They are
not strings, and the names assigned to them in the source code are not compiled into
your program, and so they are not accessible at runtime. The only way to get enum
value (i.e. sunday, monday intheaboveexample)tobeprintedistowriteafunction that
translatestheenumvalueintoastring.

Forinstance,havealookatfollowingcodesnippet:

constchar*getDayName(enumdayday1){ //outsidemain
switch(day1){
casesunday:return"sunday"
casemonday:return"monday"
/*soonforallthedays...*/
}
}
printf("%s",getDayName(d)) //callfrommain

2.3. AClassicExample
One classic example for unions and enums is to represent a value of unknown type.
Considerthedeclarationbelow:

typedefenum{Integer,String,Real,Pointer}Type
typedefstruct{
Typetype
union{
intinteger
char*string
floatreal
void*pointer
}x
}Value

Using this you can write code that handles values withoutknowingtheirexacttype.The
innerunionmustbegivenafieldnameintheouterstruct.

The program to set a value to a floating point number and to print it will be like theone
given below. In the program, we are using malloc() function to dynamically allocate
memoryforstring.

#include<stdio.h>
#include<string.h>
#include<malloc.h>

typedefenum{Integer,String,Real,Pointer}Type
typedefstruct{
Typetype //enumvariabletype
union{
intinteger
char*string
floatreal
void*pointer
}x //unionvariableu
}Value //structurevariableValue

Valuevalue_new_integer(intnumber){
Valuev
v.type=Integer
v.x.integer=number
returnv
}

Valuevalue_new_string(char*str){
Valuev
v.type=String
v.x.string=(char*)malloc(strlen(str)*sizeof(char))
strcpy(v.x.string,str)
returnv
}

Valuevalue_new_real(floatnumber){
Valuev
v.type=Real
v.x.real=number
returnv
}

Valuevalue_new_pointer(void*ptr){
Valuev
v.type=Pointer
v.x.pointer=ptr
returnv
}

intmain(){
Valuetemp=value_new_real(1.618033)
Typet=Real
if(temp.type==t)
printf("%f\n",temp.x.real)
}

3. Recursion
A function that calls itself is known as recursive function and thistechniqueisknownas
recursion in C programming. It is a fundamental technique which can be employed to
solveanyiterationbasedquestion.

3.1. AnExample
Thisprogramfindsthesumoffirstnnaturalnumbersusingrecursion.

#include<stdio.h>
intsum(intn)

intmain(){
intnum,add
printf("Enterapositiveinteger:")
scanf("%d",&num)
add=sum(num)
printf("Sumis:%d\n",add)
}
intsum(intn){
if(n==0)
returnn
else
returnn+sum(n1)//selfcalltofunctionsum()
}

In this program, sum() function is invoked from the same function. If n is not equal to 0
then, the function calls itself passing argument 1 lessthanthepreviousargumentitwas
called with. Suppose, n is 5 initially. Then, during next function calls, 4 is passed to
function and the value of argument decreases by 1 in each recursive call. When, n
becomesequalto0,thevalueofnisreturnedwhichisthesumofnumbersfrom5to1.
Forbettervisualizationofrecursioninthisexample:
sum(5)
=5+sum(4)
=5+4+sum(3)
=5+4+3+sum(2)
=5+4+3+2+sum(1)
=5+4+3+2+1+sum(0)
=5+4+3+2+1+0
=5+4+3+2+1
=5+4+3+3
=5+4+6
=5+10
=15

NOTE: Everyrecursive functionmustbeprovidedwithawaytoendtherecursion.Inthis
example when, n is equal to 0, there is no recursive call and recursion ends.Ifnobase
conditionisprovided,liken=0here,thenthecodegoesintoaninfiniteloop.

3.2. AdvantagesandDisadvantagesofRecursion
Recursion is more elegant and requires few variables which make program
clean.
Recursion can be used to replace complex nesting code bydividingtheproblem
intosameproblemofitssubtype.
Recursioncaninternallytakeupalotofmemory.Onehastoawareaboutit.

3.3. Examples
3.3.1. MergeSort
The merge sort algorithm is based on the "divide & conquer" strategy. Here, we
divide the given array to be sorted into two halves, sort these two subarrays
separately, and then combine (merge) these sortedsubarraystoproducesolution
to the original problem. For sorting the subarrays, we use recursion. In the
followingprogram,werecursivelycallthe divide()
function,tosortthearray.
As mentioned earlier we require a stopping criterion in a recursive function. So,in
the
divide( ) function, the base condition comeswhenwehavedividedthearrayto
makeitoneelementarray.Suchanarrayis,obviously,sorted.

So we start merging these arrays. In this function, the situation is detected by the
if(low<high)
condition when
low becomesequalto highmeaningthatthereisonly
one element in the array, this condition becomes false. Then, the function returns
andthecallcontrolstartsmovingbackwards.

Avisualizationfordivideandmergeisasfollows:


Therecursivecodeis:
#include<stdio.h>
voidmerge(inta[],intlow,intmid,inthigh)

voiddivide(inta[],intlow,inthigh){
if(low<high){ //Thearrayhasatleast2elements
intmid=(low+high)/2
//Recursionchaintosortfirsthalfofthearray
divide(a,low,mid)
//Recursionchaintosortsecondhalfofthearray
divide(a,mid+1,high)
merge(a,low,mid,high)
}
}

voidmerge(inta[],intlow,intmid,inthigh){
inti,j,k,m=midlow+1,n=highmid
intfirst_half[m],second_half[n]

for(i=0i<mi++) //Extractfirsthalf(alreadysorted)
first_half[i]=a[low+i]
for(i=0i<ni++) //Extractsecondhalf(alreadysorted)
second_half[i]=a[mid+i+1]

i=j=0
k=low
while(i<m||j<n){ //Mergethetwohalves
if(i>=m){
a[k++]=second_half[j++]
continue
}
if(j>=n){
a[k++]=first_half[i++]
continue
}
if(first_half[i]<second_half[j])
a[k++]=first_half[i++]
else
a[k++]=second_half[j++]
}
}

main(){
inti,n,a[10]
printf("Noofelementsinthearray::")
scanf("%d",&n)
printf("Enterarrayelements::")
for(i=0i<ni++)
scanf("%d",&a[i])

divide(a,0,n1)

printf("Sortedarray:")
for(i=0i<ni++)
printf("%d",a[i])
printf("\n")
}

3.3.2. QuickSort
QuickSort has a similar approach to Merge Sort i.e. it uses DivideandConquer
recursive algorithm to sort the values. The difference being is it's an inplace
sortingalgorithm.
ThebasicideaofQuicksortis:
1. Pick an element in the array as the pivot element. (mid element or last
elementisusuallytakenasthepivot.)
2. Make a pass to the array, called the PARTITION step, which rearranges
theelementsinthearray:
a. Thepivotelementisintheproperplace
b. Theelementslessthanpivotelementareontheleftofit
c. Theelementsgreaterthanpivotelementareontherightofit
3. Recursively apply the above process to the left and right partofthepivot
element.

Anillustrationofquicksortwithpivotasmidelement5:



Recursivecodeforquicksortwithlastelementapivot:

#include<stdio.h>
voidswap(int*a,int*b){
intt=*a
*a=*b
*b=t
}

/*Thisfunctiontakeslastelementaspivot,placesthepivot
elementatitscorrectpositioninsortedarray,andplacesall
smaller(smaller than pivot) toleftofpivotandallgreater
elementstorightofpivot*/
intpartition(intarr[],intl,inth){
intx=arr[h]
inti=(l1),j

for(j=lj<=h1j++){
if(arr[j]<=x){
i++
swap(&arr[i],&arr[j])
}
}
swap(&arr[i+1],&arr[h])
return(i+1)
}

voidquickSort(intA[],intl,inth){
if(l<h){
/*Partitioningindex*/
intp=partition(A,l,h)
quickSort(A,l,p1)
quickSort(A,p+1,h)
}
}

voidprintArr(intarr[],intn){
inti
for(i=0i<n++i)
printf("%d",arr[i])
}

intmain(){
intn,i
printf("Noofelementsinthearray::")
scanf("%d",&n)
intarr[n]
printf("Enterarrayelements::")
for(i=0i<ni++)
scanf("%d",&arr[i])
quickSort(arr,0,n1)
printArr(arr,n)
return0
}

3.4. PracticeQuestions
3.4.1. Write a program to find factorial of a number entered by theuserusinga
recursivefunction.
3.4.2. Write a program to generate the Fibonacci series for a given number
usingarecursivefunction.
3.4.3. Writeaprogramtoreverseastringusingarecursivefunction
3.4.4. Writeaprogramtoimplementbinarysearchusingrecursion.

4. SelfreferentialStructures
4.1. Recap
A selfreferential structure is a structure definition which includes at least one member
thatisapointertothesamestructure.Pointerstorestheaddressofthestructureofthe
sametype.

Thegeneralformofaselfreferentialstructureis:

structsome_struct_name{
/*otherfields,etc...*/
structsome_struct_name*pointer_name
}*some_type

Ifyouwanttousetypedef,anexamplewouldlooklike:

typedefstructnode*node_t
structnode{
intdata
node_tptr
}

Here ptr stores address of structure node. This is useful in dynamic memory allocation
and creating linked lists. node_tptr declares ptrtobeapointertoa node,notanode
itself.

See the figure given below to have a betterunderstanding.NodeA,node BandnodeC
are three nodes of the linked list. Each node has two parts:dataandlinki.e.addressof
the next node. For further clarity read the next section on dynamic memory allocation
andlinkedlists.

5. DynamicMemoryAllocation
5.1. Introduction
The exact size of array is unknown until the compile time,i.e., time when a compiler
compiles code written in a programming language into a executable form. The size of
arrayyouhavedeclaredinitiallycanbesometimesinsufficientandsometimesmorethan
required.
Dynamic memory allocation allows a program to obtain more memory space,
whilerunningortoreleasespacewhennospaceisrequired.

5.2. StaticMemoryAllocationvsDynamicMemoryAllocation
Staticmemoryallocation Dynamicmemoryallocation

In static memory allocation, memory is In dynamic memory allocation, memory


allocated while writing the C program. is allocated while executing the
Actually, user requested memory will be program.Thatmeansatruntime.
allocatedatcompiletime.

Memory size cant be modified while Memory size can be modified while
execution. execution.
Example:Array Example:Linkedlist

5.3. LibraryFunctionsforDynamicMemoryAllocation
Although, C language inherently does not have any technique to allocate memory
dynamically,thereare4libraryfunctionsunder"stdlib.h"fordynamicmemoryallocation.

5.3.1. malloc()
The name malloc stands for "memory allocation". The functionmalloc()reservesa
block of memory of specified size and return a pointer of type void which can be
castedintopointerofanyform.
Syntax:
ptr=(casttype*)malloc(bytesize)

Here, ptr is pointer of casttype. The malloc() function returns a pointer to anarea
of memory with size of byte size. If the space is insufficient, allocation fails and
returnsNULLpointer.
Example:
ptr=(int*)malloc(100*sizeof(int))

This statement will allocate either 200 or 400 according to size of int 2 or 4 bytes
respectivelyandthepointerpointstotheaddressoffirstbyteofmemory.


5.3.2. calloc()
The name calloc stands for "contiguous allocation". The only difference between
malloc() and calloc() is that, malloc() allocates single block of memory whereas
calloc() allocatesmultipleblocksofmemoryeachofsamesizeandsets allbytesto
zero.
Syntax:
ptr=(casttype*)calloc(n,elementsize)

This statement will allocate contiguous space in memory for an array of n
elements.
Example:
ptr=(float*)calloc(25,sizeof(float))

This statement allocates contiguous space in memory for an array of 25 elements
eachofsizeoffloat,i.e,4bytes.Eachofthemisinitializedtozero.

5.3.3. free()
Dynamically allocated memory with either calloc() or malloc() does not get return
onitsown.Theprogrammermustusefree()explicitlytoreleasespace.
Syntax:
free(ptr)

Thisstatementcausethespaceinmemorypointedbyptrtobedeallocated.

5.3.4. realloc()
If the previously allocated memory is insufficient ormorethansufficient.Then,you
canchangememorysizepreviouslyallocatedusingrealloc().
Syntax:
ptr=realloc(ptr,newsize)

Here,ptrisreallocatedwithsizeofnewsize.

5.4. Examples
Program to find sum of n elements entered by user. (memory allocated using
malloc)
#include<stdio.h>
#include<stdlib.h>
intmain(){
intn,i,*ptr,sum=0
printf("Enternumberofelements:")
scanf("%d",&n)
//memoryallocatedusingmalloc
ptr=(int*)malloc(n*sizeof(int))

if(ptr==NULL){
printf("Error!memorynotallocated.")
exit(0)
}

printf("Enterelementsofarray:")
for(i=0i<n++i){
scanf("%d",ptr+i)
sum+=*(ptr+i)
}

printf("Sum=%d\n",sum)
free(ptr)
return0
}

Program to find sum of n elements entered by user. (memory allocated using
calloc)
#include<stdio.h>
#include<stdlib.h>
intmain(){
intn,i,*ptr,sum=0
printf("Enternumberofelements:")
scanf("%d",&n)
ptr=(int*)calloc(n,sizeof(int))
if(ptr==NULL){
printf("Error!memorynotallocated.")
exit(0)
}
printf("Enterelementsofarray:")
for(i=0i<n++i){
scanf("%d",ptr+i)
sum+=*(ptr+i)
}

printf("Sum=%d\n",sum)
free(ptr)

return0
}

Examplefor
realloc()
#include<stdio.h>
#include<stdlib.h>
intmain(){
int*ptr,i,n1,n2
printf("Entersizeofarray:")
scanf("%d",&n1)

ptr=(int*)malloc(n1*sizeof(int))
printf("Addressofpreviouslyallocatedmemory:")
for(i=0i<n1++i)
printf("%u\t",ptr+i)

printf("\nEnternewsizeofarray:")
scanf("%d",&n2)
ptr=realloc(ptr,n2)
printf("Addressofnewlyallocatedmemory:")
for(i=0i<n2++i)
printf("%u\t",ptr+i)
printf("\n")
return0
}

5.5. Summary
ThefollowingtabletabulatesthefunctionsusedfordynamicmemoryallocationinC.

Function UseofFunction

malloc() Allocates requested size of bytesandreturnsapointertothefirstbyteof


allocatedspace

calloc() Allocates space foranarrayelements,initializestozeroandthenreturns


apointertomemory

free() Deallocatethepreviouslyallocatedspace

realloc() Changethesizeofpreviouslyallocatedspace

6. LinkedLists
6.1. Introduction
Linked lists are a way to store data with structures so that the programmer can easily
create a new place to store related data whenever necessary. Specifically, the
programmer writes a struct definition that contains variables holding information about
something, and that has a pointer to a struct of its own type (it has to be a pointer
otherwise, every time an element is created, it would create a new element, infinitely).
Each oftheseindividualstructsinthe listiscommonlyknownasanodeoranelementof
thelist.

The pointer only stores thememorylocationofanothernode.Atthe endofthelist, there
is nothing for the pointer to pointto,soitdoesnotpointtoanythingitshouldbe aNULL
pointer (NULL == 0) to prevent the node from accidentallypointingtoarandomlocation
inmemory.


Asinglylinkedlistwhosenodescontaintwofields:anintegervalueandalinktothenextnode

In a doubly linked list, each node contains a second link field pointing to the previous
node in the sequence. Thetwolinksmaybecalled nextand prev.Doublylinkedlistsare
usedwhentheabilitytotraversebothforwardsandbackwardsisrequired.


Adoublylinkedlistwhosenodescontainthreefields:anintegervalue,thelinkforwardtothenextnode,andthelink
backwardtothepreviousnode

6.2. ArraysvsLinkedlists
Arrays are stored in a contiguous chunk of memory (continuous memory locations) of
fixed size, and thus enable random access to any element given the base address (arr
or &arr or &arr[0]) and the index i (offset) of the desired element. Arrays cannot be
resizedatruntime.

Linked lists, on the other hand, acquire and release memory fromand totheOSasand
when required. This implies that there is no guarantee that neighbouring nodes will be
allocated successive memory locations. Therefore, linear traversal is the only option
available.

6.3. Examples
6.3.1. Programtocreatenode:
#include<stdlib.h>
typedefstructnode*node_t
structnode{
intx
node_tnext
}

intmain(){
/*Unchangingfirstnodepointstoanodestruct*/
node_troot=(node_t)malloc(sizeof(structnode))

/*Onlyproceedifnewmemoryissuccessfullyallocated*/
if(root!=NULL){
/*Thenoderootpointstohasitsnextpointerequalto
aNULLpointer*/
root>next=NULL

/*root>xisusedinsteadofroot.xbecauserootisa
pointer*/
root>x=5
}
}

6.3.2. Programtoprintthelistandaddanodeattheend:
It is necessary to understand how totraverse(gothrough)thelinkedlistbeforeit
really becomes useful. This will allow us to store some data in the list and later
finditwithoutknowingexactlywhereitislocated.

Let's imagine aconductorwhocanonlyenteratrainthrough thefirst carandcan
walkthroughthetraindownthelineaslongastheconnector connectstoanother
car. This is how the program will traverse the linked list. The conductor will bea
pointer to node, and it will first pointtoroot.Iftheroot'snextpointerpointing toa
valid node, the conductor (thetechnicaltermis iterator
)willbesettopointtothat
next node. In this fashion, the list can be traversed. Now, as long as there is a
pointer to a valid next node, the traversal can continue. Once itreachesaNULL
pointer, there are no more nodes, and it willbeattheendofthelist.Here'swhat
thatlookslike:
#include<stdio.h>
#include<stdlib.h>

structnode{
intx
structnode*next
}

intmain(){
/*Thiswon'tchange,orwewouldlosethelistinmemory*/
structnode*root
/*Thiswillpointtoeachnodeasittraversesthelist*/
structnode*conductor

root=malloc(sizeof(structnode))
root>next=NULL
root>x=12
conductor=root

if(conductor!=0){
while(conductor>next!=0){
conductor=conductor>next
}
}

/*Createsanodeattheendofthelist*/
conductor>next=malloc(sizeof(structnode))
conductor=conductor>next

if(conductor==0){
printf("Outofmemory")
return0
}
/*initializethenewmemory*/
conductor>next=0
conductor>x=42

return0
}

That is the basic code for traversing a list. The if statement ensures that the
memory was properly allocatedbeforetraversing thelist.Iftheconditionintheif
statement evaluates to true,thenit isokaytotry andaccessthenodepointedto
by conductor. The while loop will continue as long as thereisanotherpointerin
the next. The conductor simply moves along. It changes what it points to by
gettingtheaddressofconductor>next.

Finally,thecodeattheendcanbeusedtoaddanewnodetotheend.Oncethe
while loop has finished, the conductor will point to the last node in the array.
(Remember the conductor of the train can move on until there is nothing to
move on to? It works the same way in the while loop.) Therefore,
conductor>next is set to NULL, so it is okay to allocate a new area ofmemory
for it to point to (if it weren't NULL, then storing something else in the pointer
would cause us to lose the memory that it pointed to). When we allocate the
memory, we do a quick check to ensure that we'renotoutofmemory,andthen
the conductor traverses one more element (like a train conductor moving on to
the newly added car) and makes sure that it has its pointer tonextsetto NULL
so that the list has an end. The NULL functions like a period it means there is
no more beyond. Finally, the new node hasitsxvalueset(it canbesetthrough
userinput).

To print a linked list, the traversal function is almost the same. In our first
example, it is necessary to ensurethatthelastelementisprintedafterthewhile
loop terminates. (See if you can thinkofabetterwaybeforereadingthesecond
codeexample.)

Forexample:
conductor=root
if(conductor!=0){/*Makessurethereisaplacetostart*/
while(conductor>next!=0){
printf("%d\n",conductor>x)
conductor=conductor>next
}
printf("%d\n",conductor>x)
}

The final output is necessarybecausethewhileloopwill notrunonceitreaches
the last node, but it will still be necessary to output the contents of the next
node. Consequently, the last output deals with this. We can avoid this
redundancy byallowingtheconductortowalkoffofthebackofthetrain.Badfor
the conductor (if it were a real person), but the code is simpler asit alsoallows
us to remove the initial check for null (if root is null, then conductor will be
immediatelysettonullandtheloopwillneverbegin):

conductor=root
while(conductor!=NULL){
printf("%d\n",conductor>x)
conductor=conductor>next
}

6.3.3. SearchingaLinkedList
Searching referstothefindingofanitemordatafromagiven listofelements.So
in case of a linked list searching means finding a specific node from a specific
list. In searching operationwecomparetheKEY(itemtobesearched)valuewith
eachnodevalueinthelistinalinearfashion.Itcanbeimplementedas:

while(ptr!=NULL){
if(ptr>data==key)//Keyisthedatabesearched
printf(Itemfoundinthelist)
else
ptr=ptr>next
}

6.3.4. InsertionintoaLinkedList

There may be two possibilities for inserting a node depending upon the position
ofinsertion.Thetwowaysare:
1. Insertionatthebeginning
2. Insertioninbetween

Insertionatthebeginning:
Let us consider a pointer temp which points to the node that has to be inserted.
The data part of the new node is assigned to the data (i.e., d) through the temp
pointeras:

temp>data=d

Again we know that the start pointer points to the first node of the linked list.
Therefore, for inserting at the beginning we will have to assign start to the next
partoftempi.e.,



Now inserted node points to the next node which wasthefirstnodeofthelinked
list. So the inserted node is the first node of the linked list and start pointer is
reassignedas:

start=temp

Insertioninbetween:
For inserting a node at anyposition ofthelinkedlist(exceptatthebeginning)we
will have to firsttraversethelinkedlistforobtainingthenodeafterwhichwewant
to insert the new node. Let us consider a pointer temp which points to the node
that has to be inserted. The data part of the new node is assigned to the data
(i.e.,d)throughthetemppointeras:

temp>data=d

Again we consider a pointer q which points to the node after which we have to
insert the new node. For insertingthe elementafterthenode,weassignthe next
partofthenodetothenextpartofnewinsertednodeas:

temp>next=q>next
Thentheaddresspartofthenewinsertednodeisassignedtothenextpartofthe
previousnode.

q>next=temp


6.3.5. DeletionfromaLinkedList
An element that is to be deleted fromalinkedlististobesearchedfirst.Forthis,
the traversing operation must be carried out thoroughly on the list. After finding
theelementtheremaybetwocasesfordeletion:
1. Deletionatbeginning
2. Deletioninbetween

Deletionatbeginning:
We know that start pointer points to the firstelementofalinkedlist.Ifelementto
be deleted is the first element of linked list then we assign the value of start to
tempas:

temp=start

So now temp points to first node which has to be deleted. Now we assign the
nextpartofthedeletednodetostartas:

start=start>next

Since start points to the first element of the linked list, sostart>nextwillpointto
the second element of the linked list. Now we should free the element to be
deletedwhichispointedbytempwiththefollowingstatement:

free(temp)

Deletioninbetween:
If the element is other than the first elementof thelinkedlistthenweassignthe
next part of the deleted node to the next part of the previousnode.Thiscanbe
writtenas:

temp=q>next
q>next=temp>next
free(temp)

Here, the pointer q is pointing to the previous node of the node to be deleted.
After the first statement temp will point to the node to be deleted, after second
statement next of previous node will point to next node of the node to be
deleted.
If the node to be deleted is the last node of the linked list then the second
statementwillbeas:

q>next=NULL



6.4. Practicequestions
6.4.1. Writeaprogramtofindlengthofalinkedlist.
6.4.2. Writeaprogramtomergetwosortedlinkedlist.
6.4.3. Writeanimplementationof stack usinglinkedlist.
Stackisalineardatastructurewhichfollowsaparticularorderinwhich
theoperationsareperformed.TheorderisLIFO(LastInFirstOut).A
goodexampleofstackispileofbookswherethebookthatlastcamein
i.e.oneonthetopisthefirstonetoberemoved.
Mainlythefollowingthreebasicoperationsareperformedinthestack:
Push: Adds an item in the stack. If the stack is full, then itissaid
tobeanOverflowcondition.
Pop: Removes an item from the stack. The items are popped in
the reversed order in whichtheyarepushed. Ifthestackisempty,
thenitissaidtobeanUnderflowcondition.
Peek: Getthetopmostitem.
6.4.4. Writeanimplementationof queueusinglinkedlist.
Queueisalineardatastructurewhichfollowsaparticularorderinwhich
theoperationsareperformed.Theorderis F I
irst F
n O
irstut(FIFO).A
goodexampleofqueueisanyqueueofconsumersforaresourcewhere
theconsumerthatcamefirstisservedfirst.
Thedifferencebetweenstacksandqueuesisinremoving.Inastackwe
removetheitemthemostrecentlyaddedinaqueue,weremovetheitem
theleastrecentlyadded.
Mainlythefollowingfourbasicoperationsareperformedonqueue:
Enqueue: Addsanitemtothequeue.Ifthequeueisfull,thenitis
saidtobeanOverflowcondition.
Dequeue: Removesanitemfromthequeue.Theitemsare
poppedinthesameorderinwhichtheyarepushed.Ifthequeue
isempty,thenitissaidtobeanUnderflowcondition.
Front: Getthefrontitemfromqueue.
Rear: Getthelastitemfromqueue.
6.4.5. Writethecodefornodecreation,insertionanddeletioninadoublylinked
list.Unlikelinkedlistdonesofar,doublylinkedlistwillhavetwopointerin
eachnode: prev
andnext.

You might also like