C Languauge Notes
C Languauge Notes
DATA STRUCTURES
Sub.Code:
1BIT2C1,4BIT2C1,7BIT2C1
Handled by
PR.RAJESH MCA.,B.Ed
SYLLABUS
Introduction to C – Character set – Identifiers and keywords – Data types –
constants – Variables – declarations – Operator and Expressions – Data input,
output and control statements: Preliminaries – single character input and output
– Entering input data – Writing output data – gets and puts functions –
Branching and looping – Nested control structures Arrays: defining and
processing an array – Passing on array to functions – Multidimensional arrays –
arrays and strings.
Pointers: Fundamentals –Dynamic memory allocation – operations on pointers –
arrays of pointers
Structures and Unions: defining a structure – Structures and pointers– Self
referential structures – Bit fields – Unions – Enumerations.
Data file: Opening and Closing a data file – Creating a data file – Processing a
data file – Unformatted data file – Command line parameters.
Stack: Definition and Examples – Representing stacks in C – An example: Infix,
Postfix and Prefix. Queues and Lists: The queues and Sequential representation
– Linked lists – Lists in C.
Trees: Binary trees – Representing Lists and Binary Trees – trees and their
applications.
Session Objectives
Discuss the Origin of C
Features of C
Characteristics of C
Current Uses of C
Character Set
“C” is a Middle Level language
“C” is a Structure & Procedure Oriented Programming
language developed by Dennis Ritchie at AT&T Bell Laboratories
in USA in the Year 1972
Economy of Expressions
Modern Control Flow and Structures
Rich Set of Operators
It is Well suited for writing both System
Software like Operating Systems,
Interpreters, Editors and Assembly
Programs
UNIX Operating System was Developed by Using “C”
Language
Developing database Systems
Graphics Packages
Spread Sheets
Word Processors
Office automation
Scientific/Engineering Applications
CAD/CAM Applications
Preprocessor Directives (Incl. headerFile)
Global Variable Declarations;
void main()
{
Local Variable Declarations;
Input/Output Statements;
}
Note :
Every “C” Statements should end with Semicolon(;)
The C Program Structure
Preprocessor directives are the instructions given to the
compiler.
Syntax : #include<headerfilename.h>
Examples: #include<stdio.h>
#include<conio.h>
Stdio -> Standard Input/Output
Conio -> Console Input/Output
Void -> Keyword. It Means Returns Nothing.
main() -> It is a function name which can be used to
indicate the beginning of the program
execution
C has 32 keywords.
Instructions
Keywords
Constants,
variables &
Data Types
Alphabets,
Digits,Special
Characters
A Character denotes an alphabet, digit or a special
character. These characters can be combined to form variables.
Digits – 0,1,2,3,…7,8,9
Valid Examples :
APOLLO avg_val m1
MELUR Anu mark_1
2.Enumerated Datatype
Example :
enum mon{jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec };
Session Summary
All variables must be declared in the program before all executable statement
Every C program must contain atleast one function which must be a main()
EXERCISES
To do arithmetical calculations.
1. + Addition
2. - Subtraction
3. * Multiplication
4. / Division (Quotient)
5. % Division (Reminder)
Unary Operators:
=
• It is used to assign values to a variable.
Syntax:
Identifier=expression;
Eg:
A=2
B=5.6
Conditional Operator
printf( )
Syntax:
printf(“format string”, list of variables);
Description:
This function prints the given output on the screen.
Ex:
printf(“%d”,sum);
printf(“Enter the values for a and b”);
printf(“Sum=%d”,sum);
Character Input Output function:
putchar( );
Description:
This function converts the ASCII value of a single
character and displays the result on the monitor.
Syntax:
putchar(variable name);
Ex:
putchar(a);
Standard string Input output functions
puts( );
Syntax:
puts(variable name);
Description:
This function prints the string on the monitor.
Format of a C Program
#include<header file>
main()
{
Variable declarations;
clrscr();
Program statements;
getch();
}
EX for Operators
ARITHMETIC OPERATOR: • ASSIGNMENT AND RELATIONALAND
LOGICALOPERATOR
#include<stdio.h> #include<stdio.h>
#include<conio.h> #include<conio.h>
main() main()
{
{
int a=10,b=5;
int a,b,sum; clrscr();
clrscr(); printf(“A<=B:”,(a<=b));
printf(“\nA>=B:”,(a>=b));
printf(“Enter the values for a and b:”);
printf(“\nA==B:”,(a==b));
scanf(“%d%d”,&a,&b); printf(“\nA!=B:”,(a!=b));
sum=a+b; getch();
printf(“Sum=%d”,sum); }
getch();
}
EX for Operators
CONDITIONAL and TERNARY INCREMENT AND
OPERATOR DECREMENT OPERATOR
#include<stdio.h> #include<stdio.h>
#include<conio.h> #include<conio.h>
main() main()
{ {
int num,absolute; int i=1;
clrscr(); clrscr();
printf(“Enter any no:”); printf(“i=%d\n”,i);
scanf(“%d”,&num); printf(“i=%d\n”,++i);
absolute=(num<0)?-num:num; printf(“i=%d\n”,i);
printf(“Absolute value=%d”,absolute); getch();
getch(); }
}
EX for INPUT & OUTPUT FUNCTIONS
SINGLE CHARACTER INPUT &
STANDARD INPUT & OUTPUT OUTPUT
#include<stdio.h> #include<stdio.h>
#include<conio.h> #include<conio.h>
main( ) main()
{ {
int a,b,sum; int c;
clrscr(); clrscr();
printf(“Enter the values for a&b:”); printf(“Enter an upper case letter”);
scanf(“%d%d”,&a,&b); c=getchar();
sum=a+b; printf(“Lowercase=”);
printf(“Sum=%d”,sum); putchar(c+32);
getch( ); getch();
} }
Standard string Input output functions
#include<stdio.h>
#include<conio.h>
main( )
{
char name[30];
clrscr( );
puts(“Enter your name”);
gets(name);
puts(“Your Name is:”);
puts(name);
getch();
}
Session Objectives
Explain 8 Types of Operators
Explain Arithmetic Operators
Understand Arithmetic Expressions
Explain Relational and Logical Operators
Explain the Conditional Operators
Explain Input/Output Statement
Control Statements
It determines the flow of control in a
program Control statements
1.for statement
2. while statement
3. do while statement
Conditional control statements
if else if statement
simple if statement syntax:
Syntax: if (condition)
if (condition) statements;
Statements; else
E.g.: statements;
#include<stdio.h> eg:
#include<stdio.h>
#include<conio.h>
#include<conio.h>
main()
main()
{ {
int pos; clrscr(); int pos; clrscr();
printf(“Enter a no:”); printf(“Enter any no:”);
scanf(“%d”,&pos); scanf(“%d”,&pos);
if (pos>0) if (pos>0)
printf(“The given no is a positive printf(“The given no is a positive no”);
number”); else
getch(); printf(“The given no is a negative no”);
getch();
}
}
Nested if statement
eg:
#include<stdio.h>
#include<conio.h>
main()
{
int pos;
syntax: clrscr();
if (condition) printf(“Enter any no:”);
statements; scanf(“%d”,&pos);
elseif (condition) if(pos>0)&&(pos!=0)
statements;
else printf(“The given no is a positive no”);
statements; elseif(pos<0)&&(pos!=0)
printf(“The given no is a negative no”);
else
printf(“The given no is a zero);
getch();
}
switch case statement
It allows us to make a decision from the eg:
number of choices .The keyword case is
followed by an integer constant or a character
#include<stdio.h>
constant. #include<conio.h>
First, the expression is evaluated and if the main()
value matches any one of the case statement {
then the corresponding statement is evaluated.
If there is no match then the statements below, char code;
default is evaluated. clrscr();
Syntax: printf(“Enter a code[a/m/p]:”);
switch(expression) scanf(“%c”,&code);
{
switch(code)
case 1:statements;break;
case 2:statements;break;
{
case 3:statements;break; case ‘a’:printf(“Accounts staff”);break;
default:statements; case ‘m’:printf (“Management staff”);break;
} case ‘p’:printf (Purchase staff”);break;
default :printf (“Invalid choice ! Try again”);
} getch(); }
Looping statements
#include<stdio.h>
#include<conio.h>
while loop
main()
syntax:
{
while ( condition) int n,i=0;
{ clrscr();
printf(“Enter the range:”);
statements; scanf(“%d”,&n);
} while(i<n)
{
printf(“i=%d\n”,i);
i++;
}
getch();
}
do……. While loop
eg:
#include<stdio.h>
do……. While loop #include<conio.h>
The do while statement test the main()
condition after having executed the {
statements within the loop.
int i,n;
This means it will executes the
clrscr();
statements at least once even if the
condition fails for the first time itself. printf(“Enter the range:”);
syntax: scanf(“%d”,&n);
do do
{ {
statements; printf(‘i=%d\n”,i);
} while(condition); i++;
}while(i<n);
getch();
}
for loop
Types of Array:-
• Single/one dimensional Array
• Multi/Two dimensional Array
Intializing an Array:-
An array can be initialized when declared by specifying
the values of some or all of the elements.
Syn:-
int a[5]={1,2,3,4,5};
ONE DIMENSIONAL
ARRAY
Example
• An array with only one #include<stdio.h>
#include<conio.h>
subscript is known as void main()
{
one dimensional array. int i,a1=0,a[5];
clrscr();
• Syn:- Printf(“Enter 5 Elements:”);
for(i=0;i<5;i++)
arrayname[subscript]; {
Datatype arrayname[size]; scanf(“%d”,&a[i]);
}
for(i=0;i<5;i++)
a1=a1+a[i]; printf(“\nTotal is:%d”,a1);
}
getch();
}
FOR CHARACTER
• A character/string is stored • Example:-
#define size 256
internally as a one #include<stdio.h>#include<conio.h>
dimensional array of void main()
character. {
char a[size]; int s; clrscr();
• Each character with in the printf(“Enter a String:”); gets(a);
string will stored with one printf(“\n The array contains:%s”,a);
element of an array. for(s=0;((s<size) && (s[s]!=‘\0’);s++)
{
• Syn:- char arrayname[size]; putchar(a[s]); putchar(‘\n’);
}
printf(“\n The length of the string
is:%d”,s);
getch();
}
MULTI DIMENSIONAL ARRAY
Example:
#include<stdio.h> #include<conio.h>
An array with 2 subscripts is called
void main()
2D/MD array.
{
Syn:- datatype int a[5][5],b[5][5],c[5][5],i,j;
arrayname[subscript][subscript]; clrscr();
Intialization:- printf(“Enter A matrix:”);
datatype arrayname[rowsize][column for(i=0;i<5;i++) { for(j=0j<5;j++) {
size]; scanf(“%d”,&a[i][j]);
} } printf(“Enter B matrix:”);
(i.e) here 2 subscript are denoted as row for(i=0;i<5;i++) { for(j=0j<5;j++) {
and column . An array can be stored in scanf(“%d”,&b[i][j]); } }
the memory in 2 orders RowMajor order for(i=0;i<5;i++) { for(j=0j<5;j++) {
and Column Major Order.Usually int c[i][j]=a[i][j]+b[i][j]; printf(“RESULT IS:”);
types are stored in row major order , char for(i=0;i<5;i++) { for(j=0j<5;j++) {
types are stored in column major order. printf(“%d”,c[i][j]);
} }printf(“\n\n”); getch(); }
Session Objectives
Explain Arrays
Explain Declaration,Initialization of Array
Definition
Function is a self-contained block of programs that performs a
coherent task of some kind... Every C program can be thought of as a
collection of these functions.
There are two types of functions
1. Library functions e.g.: printf() , scanf()
2. User defined functions
User defined functions can be broadly divided into two types
1. Functions without arguments
2. Functions with arguments
Functions without arguments Implementation
1 strcpy(s1, s2);
Copies string s2 into string s1.
2 strcat(s1, s2);
Concatenates string s2 onto the end of string s1.
3 strlen(s1);
Returns the length of string s1.
4 strcmp(s1, s2);
Returns 0 if s1 and s2 are the same; less than 0 if s1<s2; greater than
0 if s1>s2.
5 strchr(s1, ch);
6 strstr(s1, s2);
Returns a pointer to the first occurrence of string s2 in string s1.
EXAMPLE
#include <stdio.h>
#include <string.h>
int main ()
{
char str1[12] = "Hello"; char str2[12] = "World"; char str3[12]; int len ;
/* copy str1 into str3 */
strcpy(str3, str1);
printf("strcpy( str3, str1) :%s\n", str3 );
/* concatenates str1 and str2 */
strcat( str1, str2);
printf("strcat( str1, str2):%s\n", str1 );
/* total lenghth of str1 after concatenation */
len = strlen(str1);
printf("strlen(str1) :%d\n", len );
return 0;
}
Session Objectives
Explain User Defined Functions
Explain Type of Functions
Discuss category of Functions
Declaration & Prototypes
Storage class in “C”
Calling the Function
A Function may call itself again and again is
called Recursive Function
The C programming language supports recursion, i.e., a function to
call itself. But while using recursion, programmers need to be careful
to define an exit condition from the function, otherwise it will go into
an infinite loop.
Function Description
Define Structure
Create Structure variable
Access structure member using . operator
Nested Structures
A union is a special data type available in C that allows to store different data types in the same memory location. You can define
a union with many members, but only one member can contain a value at any given time. Unions provide an efficient way of using the same
memory location for multiple-purpose.
Defining a Union
To define a union, you must use the union statement in the same way as you did while defining a structure. The union statement defines a new data
type with more than one member for your program. The format of the union statement is as follows −
union [union tag] {
member definition;
member definition;
...
member definition;
} [one or more union variables];
The union tag is optional and each member definition is a normal variable definition, such as int i; or float f; or any other valid variable definition.
At the end of the union's definition, before the final semicolon, you can specify one or more union variables but it is optional. Here is the way you
would define a union type named Data having three members i, f, and str −
union Data {
int i;
float f;
char str[20];
} data;
Now, a variable of Data type can store an integer, a floating-point number, or a string of characters. It means a single variable, i.e., same memory
location, can be used to store multiple types of data. You can use any built-in or user defined data types inside a union based on your requirement.
The memory occupied by a union will be large enough to hold the largest member of the union. For example, in the above example, Data type will
occupy 20 bytes of memory space because this is the maximum space which can be occupied by a character string. The following example displays
the total memory size occupied by the above union −
#include <stdio.h>
#include <string.h>
union Data {
int i;
float f;
char str[20];
};
int main( ) {
return 0;
}
When the above code is compiled and executed, it produces the following result −
Memory size occupied by data : 20
Accessing Union Members
To access any member of a union, we use the member access operator (.). The
member access operator is coded as a period between the union variable name and the
union member that we wish to access. You would use the keyword union to define variables
of union type. The following example shows how to use unions in a program −
#include <stdio.h>
#include <string.h>
union Data {
int i;
float f;
char str[20];
};
int main( ) {
data.i = 10;
data.f = 220.5;
strcpy( data.str, "C Programming");
return 0;
}
Session Objectives
Discuss Unions
Create Union variable
Access Union member using . operator
Discuss Unions of Structures
Compare Structure and Array
Difference between structure & union
A file represents a sequence of bytes, regardless of it being a text file or a binary file. C programming language
provides access on high-level functions as well as low-level (OS level) calls to handle file on your storage devices.
This chapter will take you through the important calls for file management.
Opening Files
FILE *fopen( const char * filename, const char * mode );
You can use the fopen( ) function to create a new file or to open an existing file. This call will initialize an object of
the type FILE, which contains all the information necessary to control the stream. The prototype of this function call
is as follows: Here, filename is a string literal, which you will use to name your file, and access mode can have one
of the following values:
Mode Description
w Opens a text file for writing. If it does not exist, then a new file is created. Here your
program will start writing content from the beginning of the file.
a Opens a text file for writing in appending mode. If it does not exist, then a new file is
created. Here your program will start appending content in the existing file content.
w+ Opens a text file for both reading and writing. It first truncates the file to zero
length if it exists, otherwise creates a file if it does not exist.
a+ Opens a text file for both reading and writing. It creates the file if it does not exist.
The reading will start from the beginning but writing can only be appended.
If you are going to handle binary files, then you will use the following
access modes instead of the above-mentioned ones:
Closing a File
To close a file, use the fclose( ) function. The prototype of this function is:
int fclose( FILE *fp );
The fclose() function returns zero on success, or EOF if there is an error in closing the file. This
function actually flushes any data still pending in the buffer to the file, closes the file, and
releases any memory used for the file. The EOF is a constant defined in the header file stdio.h.
There are various functions provided by C standard library to read and write a file, character by
character, or in the form of a fixed length string.
Writing a File
Following is the simplest function to write individual characters to a stream:
int fputc( int c, FILE *fp );
The function fputc() writes the character value of the argument c to the output stream referenced
by fp. It returns the written character written on success otherwise EOF if there is an error. You
can use the following functions to write a null-terminated string to a stream:
int fputs( const char *s, FILE *fp );
The function fputs() writes the string s to the output stream referenced by fp. It returns a non-
negative value on success, otherwise EOF is returned in case of any error. You can use int
fprintf(FILE *fp,const char *format, ...) function as well to write a string into a file. Try the
following example.
Make sure you have /tmp directory available. If it is not, then before proceeding, you must create
this directory on your machine.
Example 1: Write to a text file using
fprintf() Reading from a text file
Example 2: Read from a text file using
fscanf()
#include <stdio.h>
int main()
#include <stdio.h>
{
int main()
int num;
{
FILE *fptr;
int num;
fptr = fopen("C:\\program.txt","w");
FILE *fptr;
if(fptr == NULL)
if ((fptr = fopen("C:\\program.txt","r"))
{
== NULL){
printf("Error!");
printf("Error! opening file");
exit(1);
// Program exits if the file pointer
} returns NULL.
printf("Enter num: "); exit(1);
scanf("%d",&num); }
fprintf(fptr,"%d",num); fscanf(fptr,"%d", &num);
fclose(fptr); printf("Value of n=%d", num);
return 0; fclose(fptr);
} return 0;
}
Session Objectives
Explain files
Not all procedures can be called an algorithm. An algorithm should have the
following
characteristics −
Unambiguous − Algorithm should be clear and unambiguous. Each of its steps
(or phases), and their inputs/outputs should be clear and must lead to only one
meaning.
Input − An algorithm should have 0 or more well-defined inputs.
Output − An algorithm should have 1 or more well-defined outputs, and should
match the desired output.
Finiteness − Algorithms must terminate after a finite number of steps.
Feasibility − Should be feasible with the available resources.
Independent − An algorithm should have step-by-step directions, which should
be independent of any programming code.
How to Write an Algorithm?
There are no well-defined standards for writing algorithms. Rather, it is problem and
resource dependent. Algorithms are never written to support a particular programming
code.
As we know that all programming languages share basic code constructs like loops
(do, for, while), flow-control (if-else), etc. These common constructs can be used to write
an algorithm.
We write algorithms in a step-by-step manner, but it is not always the case. Algorithm
writing is a process and is executed after the problem domain is well-defined. That is,
we
should know the problem domain, for which we are designing a solution.
Example
Let's try to learn algorithm-writing by using an example.
Problem − Design an algorithm to add two numbers and display the result.
step 1 − START
step 2 − declare three integers a, b & c
step 3 − define values of a & b
step 4 − add values of a & b
step 5 − store output of step 4 to c
step 6 − print c
step 7 − STOP
Algorithms tell the programmers how to code the program. Alternatively, the algorithm
can be written as −
step 1 − START ADD
step 2 − get values of a & b
step 3 − c ← a + b
step 4 − display c
step 5 − STOP
In design and analysis of algorithms, usually the second method is used to describe an
algorithm. It makes it easy for the analyst to analyze the algorithm ignoring all unwanted
definitions. He can observe what operations are being used and how the process is flowing.
Writing step numbers, is optional.
STACK
A stack is an Abstract Data Type (ADT), commonly used in most
programming languages. It is named stack as it behaves like a real-
world stack, for example – a deck of cards or a pile of plates, etc.
A real-world stack allows operations at one end only. For example, we can
place or remove a card or plate from the top of the stack only. Likewise,
Stack ADT allows all data operations at one end only. At any given time, we
can only access the top element of a stack.
This feature makes it LIFO data structure. LIFO stands for Last-in-first-out.
Here, the element which is placed (inserted or added) last, is accessed first.
In stack terminology, insertion operation is called PUSH operation and
removal operation is called POP operation.
Stack Representation
The following diagram depicts a stack and its operations −
2 (a + b) * c *+abc ab+c*
3 a * (b + c) *a+bc abc+*
5 (a + b) * (c + d) *+ab+cd ab+cd+*
The above table shows the default behavior of operators. At any point of time in
expression evaluation, the order can be altered by using parenthesis. For example . In
a+b*c, the expression part b*c will be evaluated first, with multiplication as
precedence over addition. We here use parenthesis for a+b to be evaluated first, like
(a+b)*c.
Postfix Evaluation Algorithm
We shall now look at the algorithm on how to evaluate postfix notation −
Step 1 − scan the expression from left to right
Step 2 − if it is an operand push it to stack
Step 3 − if it is an operator pull operand from stack and perform operation
Step 4 − store the output of step 3, back to stack
Step 5 − scan the expression until all operands are consumed
Step 6 − pop the stack and perform operation
QUEUE :
• It is a non-primitive, linear data structure, and a subclass of list data
structure.
• Two operation are frequently carried on queue. They are insertion and
deletion.
• The deletion is possible when the queue contains at least one element.
• Queue is an abstract data structure, somewhat similar to Stacks. Unlike stacks,
a queue is open at both its ends. One end is always used to insert data
(enqueue) and the other is used to remove data (dequeue). Queue follows First-
In-First-Out methodology, i.e., the data item stored first will be accessed first.
Queue Representation
As we now understand that in queue, we access both ends for
different reasons. The following diagram given below tries to
explain queue representation as data structure −As in stacks, a
queue can also be implemented using Arrays, Linked-lists,
Pointers and Structures. For the sake of simplicity, we shall
implement queues using one-dimensional array.
Basic Operations
peek()
Queue operations may involve initializing or This function helps to see the data at
defining the queue, utilizing it, and then completely the front of the queue. The algorithm
erasing it from the memory. Here we shall try to of peek() function is as follows −
understand the basic operations associated with
queues − begin procedure peek
•enqueue() − add (store) an item to the queue.
return queue[front]
•dequeue() − remove (access) an item from the
queue.
end procedure
Few more functions are required to make the above- Implementation of peek() function in C
mentioned queue operation efficient. These are − programming language −
peek() − Gets the element at the front of the queue
without removing it. int peek()
isfull() − Checks if the queue is full. {
isempty() − Checks if the queue is empty. return queue[front];
In queue, we always dequeue (or access) data,
}
pointed by front pointer and while enqueing (or
storing) data in the queue we take help of rear
pointer.
Let's first learn about supportive functions of a
queue
isfull() isempty()
As we are using single dimension array Algorithm of isempty() function −
to implement queue, we just check for
begin procedure isempty
the rear pointer to reach at MAXSIZE
to determine that the queue is full. In if front is less than MIN OR front is
case we maintain the queue in a greater than rear return true
circular linked-list, the algorithm will else
differ. Algorithm of isfull() function − return false
begin procedure isfull endif
if rear equals to MAXSIZE end procedure
return true else If the value of front is less than MIN or
return false 0, it tells that the queue is not yet
Endif end procedure initialized, hence empty.
Implementation of isfull() function in C
programming language − bool isempty() {
bool isfull() { if(front < 0 || front > rear)
if(rear == MAXSIZE - 1) return true;
return true; else
Else return false; return false;
} }
Enqueue Operation
Queues maintain two data pointers, front and rear. Therefore, its
operations are comparatively difficult to implement than that of stacks.
The following steps should be taken to enqueue (insert) data into a queue
−
Step 1 − Check if the queue is full.
Step 2 − If the queue is full, produce overflow error and exit.
Step 3 − If the queue is not full, increment rear pointer to point the next
empty space.
Step 4 − Add data element to the queue location, where the rear is
pointing.
Step 5 − Return success.
Algorithm for enqueue Operation
procedure enqueue(data)
if queue is full
return overflow
endif
rear ← rear + 1
queue[rear] ← data
return true
end procedure
Implementation of enqueue() in C
programming language −
int enqueue(int data)
if(isfull())
return 0;
rear = rear + 1;
queue[rear] = data;
return 1;
end procedure
Dequeue Operation
dequeue operation −
Similar steps should be taken if the node is being inserted at the beginning of the list.
While inserting it at the end, the second last node of the list should point to the new
node and the new node will point to NULL.
Deletion Operation
Deletion is also a more than one step process. We shall learn with pictorial
representation.
First, locate the target node to be removed, by using searching algorithms.
The left (previous) node of the target node now should point to the next
node of the target node −
We need to use the deleted node. We can keep that in memory otherwise we can simply deallocate memory and
wipe off the target node completely.
Reverse Operation
This operation is a thorough one. We need to make the last node to be pointed by the head node and reverse the
whole linked list.
First, we traverse to the end of the list. It should be pointing to NULL. Now, we shall make it point to
its previous node −
We have to make sure that the last node is not the lost node. So we'll have some temp node, which
looks like the head node pointing to the last node. Now, we shall make all left side nodes point to their
previous nodes one by one.
Except the node (first node) pointed by the head node, all nodes should point to their predecessor, making
them their new successor. The first node will point to NULL.
We'll make the head node point to the new first node by using the temp node.
Doubly Linked List is a variation of Linked list in which navigation is possible in both ways, either forward and
backward easily as compared to Single Linked List. Following are the important terms to understand the concept of
doubly linked list.
• Link − Each link of a linked list can store a data called an element.
• Next − Each link of a linked list contains a link to the next link called Next.
• Prev − Each link of a linked list contains a link to the previous link called Prev.
• Linked List − A Linked List contains the connection link to the first link called First and to the last link called Last.
As per the above illustration, following are the important points to be considered.
• Doubly Linked List contains a link element called first and last.
• Each link carries a data field(s) and a link field called next.
• Each link is linked with its next link using its next link.
• Each link is linked with its previous link using its previous link.
• The last link carries a link as null to mark the end of the list.
Basic Operations
Following are the basic operations supported by a list.
• Insertion − Adds an element at the beginning of the list.
• Deletion − Deletes an element at the beginning of the list.
• Insert Last − Adds an element at the end of the list.
• Delete Last − Deletes an element from the end of the list.
• Insert After − Adds an element after an item of the list.
• Delete − Deletes an element from the list using the key.
• Display forward − Displays the complete list in a forward manner.
• Display backward − Displays the complete list in a backward manner.
Insertion Operation
Following code demonstrates the insertion operation at the beginning of a doubly
linked list.
//insert link at the first location
void insertFirst(int key, int data) {
//create a link
struct node *link = (struct node*) malloc(sizeof(struct node));
link->key = key; link->data = data; if(isEmpty()) {
//make it the last link last = link; }else {
//update first prev link head->prev = link; }
//point it to old first link
link->next = head;
//point first to new first link
head = link; }
Deletion Operation Insertion at the End of an Operation
Following code demonstrates the Following code demonstrates the insertion
deletion operation at the operation at the last position of a doubly linked
beginning of a doubly linked list. list.
//delete first item //insert link at the last location
struct node* deleteFirst() { void insertLast(int key, int data) {
//save reference to first link //create a link
struct node *tempLink = head; struct node *link = (struct node*)
//if only one link malloc(sizeof(struct node));
if(head->next == NULL) { link->key = key;
last = NULL; link->data = data;
}else { if(isEmpty()) {
head->next->prev = NULL; //make it the last link
} last = link;
head = head->next; }else {
//return the deleted link //make link a new last link
return tempLink; last->next = link;
} //mark old last node as prev of new link
link->prev = last;
}
//point last to new last node
last = link;
}
Tree represents the nodes connected by edges. We will discuss binary tree or binary search tree
specifically.
Binary Tree is a special datastructure used for data storage purposes. A binary tree has a special
condition that each node can have a maximum of two children. A binary tree has the benefits of
both an ordered array and a linked list as search is as quick as in a sorted array and insertion or
deletion operation are as fast as in linked list.
Important Terms
Following are the important terms with respect to tree.
• Path − Path refers to the sequence of nodes along the edges of a tree.
• Root – The node at the top of the tree is called root. There is only one root per tree and one path from the root node to
any node.
• Parent − Any node except the root node has one edge upward to a node called parent.
• Child – The node below a given node connected by its edge downward is called its child node.
• Leaf – The node which does not have any child node is called the leaf node.
• Subtree − Subtree represents the descendants of a node.
• Visiting − Visiting refers to checking the value of a node when control is on the node.
• Traversing − Traversing means passing through nodes in a specific order.
• Levels − Level of a node represents the generation of a node. If the root node is at level 0, then its next child node is at
level 1, its grandchild is at level 2, and so on.
• Keys − Key represents a value of a node based on which a search operation is to be carried out for a node.