Vous êtes sur la page 1sur 58

-Ms.

Pranoti sk
Fundamentals of algorithm analysis: Big „O‟ notations,
Time and space complexity of algorithms., Elementary
data structures and their applications
Arrays: ordered lists, representation of arrays, sparse
matrices, linked lists: singly and doubly linked lists,
stacks, queues, multiples stacks and queues,
Applications: polynomial arithmetic, infix, postfix and
prefix arithmetic expression conversion and evaluations.
Types of Data Structures
 Basic DS: Int, Float, Char...
 Advanced DS
 Linear
○ Arrays (1 Dimensional)
○ Arrays (2 Dimensional)
○ Linked List (Singly, Doubly, Circular)
○ Stacks
○ Queues
 Non Linear
○ Trees
○ Graphs
Philosophy/ Motivation
 Ease of insertion/ deletion/ modification
 Random access or access at particular
instances
 Cost and benefits
 No perfect DS!
 DS changes over time
Arrays (1 Dimensional)
 Arrays is the finite collection of same data
elements stored in contiguous memory
locations.
 First element starts from 0th position.
 It basically is set of pairs <index, value>. Each
index is mapped to single value in the set.
 ex. Int array[5]; it allocates 10 bytes and retains
the address of the 0th location.
 The address of the 0th (first) location is called
base address.
 On the basis of base address, we can calculate
the position of any element in the array using
formula (base address + i*sizeof(datatype))
 Example.
Array Passing
#define Max_Size 100
int sum(int [],int)
int array[Maz_Size],ans,i;
void main()
{ for(i=0; i<Maz_Size; i++)
array[i] = i;
ans = sum(array,Max_Size);
printf(“The sum of array elements : %d”,ans);
}

int sum(int f_array[], int n)


{ temp_sum = 0;
for(i=0; i<n; i++)
temp_sum = temp_sum + f_array[i];
return temp_sum;
}
Array Addressing
Invoked as print (&array[0],5).
void print (int *ptr, int n)
{
int i;
printf(“address\tcontents\n”);
for (i=0; i< n; i++)
printf(“%5u \t %d \n”,(ptr+i),*(ptr+i));
}
Dynamic Memory Allocation of
1D Array
//#define Malloc(a,s)
void main()
{ int i,n,*array;
printf(“enter size of array”);
scanf(“%d”,&n);
//array=malloc(n*sizeof(int));
//Malloc(array, n*sizeof(int));
...
}
Typical Operations on Arrays
1. Traversing the array
2. Display the elements of an array
3. Inserting an element
4. Deleting an element
5. Updating an element
6. Searching an element
7. Merging two arrays
8. Reversing the elements of an array
Inserting an Element in an Array
void insert(int *array, int loc, int value)
{ int i;
for (i=max_size; i>=loc; i--)
array[i] = array[i-1];
array[i]=value;
}
 Examples: insert (array,1,10), insert
(array,10,20), insert (array,4,15)
Deleting an Element in an Array
void delete(int *array, int loc)
{ int i;
for (i=loc; i<Max_Size; i++)
array[i-1] = array[i];
array[i-1] = 0;
}
 Examples:delete(array, 7), delete(array, 3)
Updating an Element in an Array
void update(int *array, int value, int new_value)
{ int i;
for(i=0; i<Max_Size; i++)
{ if(array[i]==value)
array[i]=new_value;
}
if(i==Max_Size)
printf(“Element not present in the Array”);
}
 Example: update(array, 10, 20)
Searching an Element in an Array
void find(int *array, int value)
{ int i;
for(i=0; i<Max_Size; i++)
{ if(array[i]==value)
{ printf(“Element found at %d location”,i+1);
return;
}
}
if(i==Max_Size)
printf(“Element not present in the Array”);
}
 Example: find(array, 10)
Merging two Arrays
int* merge(int *array1, int *array2)
{ int *array3,i,k=0;
size=Max_Size1+Max_Size2;
array3=(int *)malloc(size*sizeof(int));
for(i=0; i<Max_Size1; i++)
{ array3[k]=array1[i];
k++;
}
for(i=0; i<Max_Size2; i++)
{ array3[k]=array2[i];
k++;
}
return array3;
}
 Example: ans=merge(array1,array2);
Reversing Elements of an Array

void reverse (int *array)


{ int i,temp;
for(i=0; i<Max_Size/2; i++)
{ temp=array[i];
array[i]=array[Max_Size-1-i];
array[Max_Size-1-i]=temp;
}
}
 Example: reverse(array) (both odd and
even length array reversing works well);
Arrays (2 Dimensional)
 Elements are placed in the form of matrix. Ex. int
array[3][5];
 Matrix is just for imagination. Actually representation is
contiguous.
 Row major arrangement and Column major arrangement.
 Address calculations:
 For Row major: Base Address + (i*cols+j)*datatype size
 For Column major: Base Address + (j*rows+i)* datatype
size
for(i=0; i<3; i++)
{ for(j=0; j<5; j++)
scanf(“%d”,&array[i][j]);
}
Operations on 2D Arrays: Addition, Multiplication, Transpose.
Addition of 2D Arrays
void add(int array1[3][3], int array2[3][3], int
array3[3][3])
{ int i,j;
for(i=0; i<3; i++)
{ for(j=0; j<3; j++)
array3[i][j]=array1[i][j]+array2[i][j];
}
}
 Example: add(array1,array2,array3)
Multiplication of 2D Arrays
void mul(int array1[r1][c1], int array2[r2][c2], int array3[r3][c3])
{ int i,j;
if (c1==r2)
{ for(i=0; i<r1; i++)
{ for(j=0; j<c2; j++)
{ array3[i][j]=0;
for(k=0; k<c1; k++)
array3[i][j]=array3[i][j]+array1[i][k]*array2[k][j];
}
}
}
else
printf(“Incompatible matrices”);
}
 Example: mul(array1,array2,array3)
Transpose of a 2D Array
void transpose(int array1[3][3], int
array2[3][3])
{ int i,j;
for(i=0; i<3; i++)
{ for(j=0; j<3; j++)
array2[i][j]=array1[j][i];
}
}
 Example: transpose(array1,array2)
Structures
struct{ char name[10];
int age;
float salary} person;
Usage: strcpy(person.name,’abc’);
person.age=10;
person.salary=35000;
typedef struct { char name[10];
int age;} humanbeing;
Usage: humanbeing person1,person2;
strcpy(person1.name,person2.name)
person1.age=person2.age
Self Referential Structure
typedef struct { int month;
int day;
int year;} date;
typedef struct { char name[10];
int age;
date dob;} humanbeing;
Usage: humanbeing person;
person.name=‘abc’
person.age=30;
person.dob.month=1;
person.dob.day=1;
person.dob.year=2013;
Sparse Matrices
 Sparse Matrix: Matrix with too many zeros.
Waste of space.
#define Max_Terms 100
typedef struct { int col;
int row;
int value;} term;
term matrix[Max_Terms];
 0th location stores the number of rows, cols and
non zero values.
 Ascending order of rows followed by ascending
order of columns.
 Example.
Transpose of a Sparse Matrix
1. for each row i
take element <i,j,value> and store it as
element <j,i,value> of the transpose. Ex.
2. for all elements in column j
place element <i,j,value> in element
<j,i,value> of the transpoes. Ex.
void transpose(term matrix[], term m_trans [])
{ n=matrix[0].value;
m_trans[0].row=matrix[0].col;
m_trans[0].col=matrix[0].row;
m_trans[0].value=matrix[0].value;
if (n>0)
current=1;
for(i=0;i<matrix[0].col;i++)
{ for(j=1;j<=n;j++)
{ if(matrix[j].col==i)
{ m_trans[current].row=matrix[j].col;
m_trans[current].col=matrix[j].row;
m_trans[current].value=matrix[j].value;
current++;
}
}
}
} complexity: O(columns.elements)
Linked List
 Arrays have fixed dimension.
 Insertion and deletion are time consuming operation.
 Arrays place second element right next to first element always.
Contiguous memory allocation may not be possible every time.
 The elegant solution to these disadvantages of arrays is Linked
List(LL).
 Elements are placed at different locations. The only major
requirement is to know the address of first element (head). I
 The insertion and deletion of arbitrary element is easier in LL.
 Elements can be placed anywhere in the memory and
connected by a link.
 Each data element may have one or more data fields and one or
more link/pointers. Ex.
 Each element has exactly one link associated with it.
 Last element’s link is 0/NULL.
Typical Operations on Linked List
1. Creating the LL
2. Traversing the LL
3. Display the elements in LL
4. Inserting a node in LL
5. Deleting a node in LL
6. Updating an element in LL
7. Searching an element in LL
8. Merging two LLs
9. Reversing the elements of a LL
 Creating (structure) of a LL:
Struct node { int data; struct node *link; } ;
//main block: struct node *head;
Inserting elements into LL
 3 functions to insert an element at every possible location in
LL (ex. addatbeg, addatend, addafter)
 Add node at the beginning
 Steps: Create new node, assign data elements, set it as head.
void addatbeg(struct node **head, int value)
{ struct node *new;
new=malloc(sizeof(struct node));
new data=value;
newlink=*head;
*head=new;}
 Displaying the LL
void display (struct node *head)
{ while (head!=NULL)
{ printf(“%d”,headdata); head=headlink;}
}
 Add node at the end
 Steps:
 If list is empty: Create new node, assign data elements, set it as
head.
 Else: Traverse till the end of list, create new node, assign data
elements, set its link at the end of list.
void addatend (struct node **head, int value)
{ struct node *temp,*new;
if (*head==NULL)
{ new=malloc(sizeof(struct node));
new data=value; newlink=NULL;
*head=new;}
else
{ temp=*head;
while(templink!=NULL) temp=templink;
new=malloc(sizeof(struct node));
newdata=value; templink=new;} }
 Add node at particular location
 Steps:
 Find the desired location, create new node, assign data
elements, set its link to temp’s link and temp’s link to new.
void addafter (struct node *head, int loc, int value)
{ struct node *temp,*new;
int i;
temp=head;
for(i=0;i<loc;i++)
temp=templink;
new=malloc(sizeof(struct node));
new data=value;
newlink=templink;
templink=new;
}
Deleting node form LL
 Steps:
 Traverse LL till the node is found
 If the node to be deleted is first node, simply make temp’s link as head.
 Else assign previous node’s link to temp’s link
void delete (struct node **head, int value)
{ struct node *prev, *temp;
temp=*head;
while(temp!=null)
{ if (tempdata==value)
{ if(temp==*head) *head==templink;
else prevlink=templink;
free(temp); return; }
else
{ prev=temp;
temp=templink;}
}
}
Updating an element in LL
 Steps: find the value by traversing the linked list. When
element found update
 Traverse the LL to search the value to be updated. Modify the
value
void update(struct node **head, int value, int new_value)
{ struct node *temp; int flag=0;
temp=*head;
while(temp!=null)
{
if (tempdata==value)
{ tempdata=new_value; flag=1;

else
temp=templink;
}
if(flag==0) printf(“Element not found in the list.”);
}
Reversing the LL
void reverse (struct node **head)
{ struct node *temp1,*temp2,*temp3;
temp1=*head;
temp2=null;
while(temp1!=null)
{ temp3=temp2;
temp2=temp1;
temp1=temp1link;
temp2link=temp3;
}
*head=temp2;
}
Doubly Linked List
 Disadvantage of SLL is that we can proceed only in the
direction of links.
 The only way to reach the previous node is to start over all
again form first node.
 If the problem requires us to move in both directions, we
use DLL
 Each node has two pointers, one in the forward direction
whereas the other in backward direction
 The node has at least 3 fields, a data field, a left link (llink),
a right link (rlink)
 struct node
{ int data;
struct node *prev;
struct node *next;};
Inserting elements into DLL
 Add node at the beginning
void addatbeg(struct node **head, int value)
{ struct node *new;
new=malloc(sizeof(struct node));
new data=value;
newprev(llink)=NULL;
newnext(rlink)=*head;
*headprev=new;
*head=new;}
 Displaying the LL
void display (struct node *head)
{ while (head!=NULL)
{ printf(“%d”,headdata); head=headnext;}
}
 Add node at the end
void append (struct node **head, int value)
{ struct node *temp,*new;
if (*head==NULL)
{ new=malloc(sizeof(struct node));
new data=value;
newprev=NULL; newnext=NULL;
*head=new;}
else
{ temp=*head;
while(tempnext!=NULL) temp=tempnext;
new=malloc(sizeof(struct node));
newdata=value;
newnext=NULL; newprev=temp;
tempnext=new;}
}
 Add node at particular location
void addafter (struct node *head, int loc, int value)
{ struct node *temp,*new;
int i;
temp=head;
for(i=0;i<loc;i++)
temp=templink;
new=malloc(sizeof(struct node));
new data=value;
newprev=temp;
newnext=tempnext;
tempnextprev=new;
tempnext=new;
}
Deleting node form DLL
void delete (struct node **head, int value)
{ struct node *prev, *temp;
temp=*head;
while(temp!=null)
{ if (tempdata==value)
{ if (temp==*head)
{ *head=*headnext;
*headprev=NULL;}
else
{ if(tempnext==NULL)
tempprevnext=NULL;
else
{ tempprevnext=tempnext;
tempnextprev=tempprev;}
}
} free(temp):
else temp=tempnext; }}
Circular and Doubly Circular
Linked List
 SLL is a powerful data structure, yet it can not support
to reach any already traversed node. CLL has solved
the problem. Instead last node’s link pointing NULL, in
CLL last node’s link points to the first node.
 DCLL: in addition to nodes storing data, DCLL
possesses one more node called header node. The
data part of header node has no information stored.
Stacks
 A stack is an ordered list in which
insertion/push/add and deletion/pop/remove
operations are performed at only one end.
 Simplest implementation is using 1D array, except
that we can not arbitrarily delete any element except
last.
 The only active end in stack is top ie, stack grows
and shrinks at only one end. Elements are inserted
and deleted from top.
 Push: insertion of element in stack.
 Pop: deletion of element from stack.
 LIFO structure.
 Stack using Array.
 Stack using LL.
 top is always initialized to -1 to denote empty stack.
Stack as Array: struct stack { int array[max_size], int top;};
//main block: struct stack s;
void init_stack( struct stack *s)//initialize stack
{ s.top=-1;}
void push (struct stack *s, int data)
{ if (stop==max_size-1)
{ printf(“stack full”); }
stop++;
sarray[stop]=data; }
int pop (struct stack *s)
{ if (stop==-1)
{ printf(“stack empty”);
return null; }
data=sarray[stop];
stop--;
return data; }
Stack as Linked List: struct stack { int data; struct stack *next;};
// main block: struct stack *top=NULL;
void push (int value)
{ struct stack *temp;
temp=(struct stack *) malloc sizeof(struct stack));
tempdata=value;
if(top==NULL)
{ top=temp;
topnext=null; }
else
{ tempnext=top;
top=temp; } }
int pop()
{ struct stack *temp;
if(top==NULL)
{ printf(“Stack empty”); return null; }
else
{ temp=top;
value=tempdata;
top=topnext; free(temp);
return value; }}
Queues
 A stack is an ordered list in which
insertion/push/add and deletion/pop/remove
operations are performed at different ends.
 The end at which new elements are added is
called as rear, whereas the end from which
elements are deleted is called as front.
 FIFO lists
 Queue using Array
 Queue using Linked List
 Front and Rear always initialized to -1.
 Queue using Array
void insert()
{ if(rear == max-1)
printf(“Queue is full.");
else
{ printf(“Enter data: ");
scanf("%d", &data);
if (rear == -1 && front == -1)
{ rear = 0; front = 0;
}
else
rear++;
queue[rear] = data;
printf(“Data inserted: %d", data);
}
}
void delete()
{ if(front == -1)
printf(“Queue is empty.");
else
{ data = queue[front];
if (front == rear)
{ front = -1; rear = -1;}
else
front++;
printf(“Data deleted: %d", data);} }
void display()
{ int i;
if(front == -1)
printf(“Queue is empty.");
else
{ for(i=front; i<=rear; i++)
printf(" %d", queue[i]);} }
 Queue using Linked List:
struct node { int data;
struct node *next;} *front, *rear;
// set rear, front to NULL in main block
void enqueue(int value)
{ struct node *temp;
temp = (struct node*)malloc(sizeof(struct node));
if(temp==NULL)
printf (“Queue is full.”)
tempdata = value;
tempnext = NULL;
if (rear == NULL || front == NULL)
front = temp; rear = temp;
else
{ rearnext = temp;
rear = temp; } }
int dequeue() { struct node *temp; int value;
if (front == NULL || rear == NULL)
{ printf(“Queue is empty);
getch(); exit(0);}
else
{ temp = front; value = tempdata;
front = frontnext; free(temp);}
return (value);}
void display() { struct node *temp; temp = front;
while (front == NULL || rear == NULL)
{ printf("\nQueue is empty");
getch(); exit(0); }
while (temp != NULL)
{ printf("%d", temp->data);
temp = tempnext;
}
Polynomials using Arrays
 First structure
#define Max_Degree 101
tyoedef struct { int degree;
int coef[Max_Degree];} polynomial;
 Space wastage!!!
 Second structure
#define Max_Terms 100
typedef struct { int expon; int coef; }polynomial;
polynomial terms[max_terms];
 Indicators: start_a, finish_a,start_b,finish_b,avail; (diagram)
 While accepting polynomials: assign avail to 1, start_a and
finish_a to 0;
 void attach(int coef, int expon)
 {terms[avail].coef=coef; terms[avail].expon=epon; avail++;}
void add(int start_a, int finish_a, int start_b, int finish_b, int *start_d, int
*finish_d)
{ int coefficient; *start_d=avail;
while (start_a<=finish_a && start_b<= finish_b)
{ switch (compare(terms[start_a].expon,terms[start_b].expon))
{ case -1: attach(terms[start_b].coef,terms[start_b].expon);
start _b++; break;
case 0: coefficient = terms[start_a].coef+terms[start_b].coef;
if (coefficient)
attach (coefficient, terms[start_a].expon);
start_a++; start_b++; break;
case 1: attach(terms[start_a].coef,terms[start_a].expon);
start _a++; break; } }
for(;start_a<=finish_a;start_a++)
attach(terms[start_a].coef,terms[start_a].expon);
for(;start_b<=finish_b;start_b++)
attach(terms[start_b].coef,terms[start_b].expon);
*finish_d=avail-1; }
Polynomials using Linked Lists
struct polynode{ int coef; int expon;
struct polynode *link;}
//struct polynode a,b,c;
void attach(int coef, int expon, polynode *rear)
{
polynode temp;
temp=malloc(sizeof(*temp));
tempcoef=coef;
tempexpon=expon;
*rearlink temp;
*rear=temp;
}
polynode add(polynode a,polynode b)
{ polynode c, rear, temp; int sum;
rear=malloc(sizeof(*rear)); c=rear;
while(a && b)
{ switch(compare(aexpon, bexpon))
{
case -1: attach(bcoef, bexpon, &rear);
b=blink; break;
case 0: sum=acoef+bcoef;
if(sum)
attach(sum, aexpon, &rear);
a=alink; b=blink; break;
case 1: attach(acoef, aexpon, &rear);
a=alink; break; } }
while(a!=NULL)
{ attach(acoef, aexpon, &rear); a=alink; }
while(b!=NULL)
{ attach(bcoef, bexpon, &rear); b=blink; }
rearlink=NULL;
temp=c; c=clink; free(temp);
return c; }
Searching
 Linear Search:
 Binary Search:
int search(int array[],int num, int left, int right)
{ int middle;
while(left<=right)
{ middle=(left+right)/2
switch((compare(array[middle],num))
{ case -1: left=middle+1; break;
case 0: getch() exit (0); return middle;
case 1: right=middle-1; } }
return -1;
}
int compare(int x,int y)
{ if(x<y) return -1;
else if (x==y) return 0;
else return 1;
}
Application of Stacks: Infix Postfix Prefix
Arithmetic Expressions, Conversion and
Evaluation
 Need for Polish notations (prefix and postfix)
 Position of operators and operands
determine the order.
 Priority: [**($)(^),*,/,+,-]
 Prefix: operator comes before operands. Ex.
 Postfix: operands come before operator. Ex.
 Operands maintain order, no need of
brackets and operator preference is not
required.
Infix to Prefix
 Two arrays target and stack of maximum size are used. Stack
array stores contents on stack whereas target array stores
prefix expression string so far.
 Accept the expression string from user.
 Initialization of target array and stack array to empty, top
pointer to -1, length of expression string to 0.
 Reverse the expression. Find out the length. Append ‘\0’ to
target array. Target array starts from back.
 Push function checks top for max size and pushes the
operator.
 Pop function checks top for max size and returns the element.
 Priority function sets the priority of each operator [($,**,^: 3),
(*,/,%: 2), (+,-: 1) else 0]
 struct: int top, l. char target[max],stack[max],char *s,*t.
 Convert function: while (expression string doesn't end)
1. If char scanned is ‘ ’,’\t’-> move forward.
2. If char scanned is digit or alpha (isdigit/isalpha) -> add to
target array. Pointer decrement.
3. If char scanned is ‘)’-> push on stack
4. If char scanned is *,/,%,+,-,**($,^)-> if(top!=-1) pop
operator, check priority. While (opr priority > scanned char.
priority)add to target array. Pointer decrement. Pop next
opr.
Push operator on stack. Push scanned char. on stack. Else
push scanned char. on stack
5. If char scanned is ‘(‘-> pop operator. While opr!=‘)’ add to
target array. Pointer decrement. Pop operator
6. If top!=-1 add remaining all operators in stack to target
array.
 Print the target array. 4$2*3-3+8/4/(1+1)
Infix to Postfix
 Two arrays target and stack of maximum size are used.
Stack array stores contents on stack whereas target array
stores prefix expression string so far.
 Accept the expression string from user.
 Initialization of target array and stack array to empty, top
pointer to -1.
 Push function checks top for max size and pushes the
operator.
 Pop function checks top for max size and returns the
element.
 Priority function sets the priority of each operator [($,**,^: 3),
(*,/,%: 2), (+,-: 1) else 0]
 Struct: int top. char target[max],stack[max],char *s,*t.
 Convert function: while (expression string doesn't end)
1. If char scanned is ‘ ’,’\t’-> move forward.
2. If char scanned is digit or alpha (isdigit/isalpha) -> add to
target array. Pointer increment.
3. If char scanned is ‘(’-> push on stack
4. If char scanned is *,/,%,+,-,**($,^)-> if(top!=-1) pop
operator, check priority. While (opr priority >= scanned
char. priority)add to target array. Pointer increment. Pop
next opr.
Push operator on stack. Push scanned char. on stack.
Else push scanned char. on stack
5. If char scanned is ‘)‘-> pop operator. While (opr!=‘)’) add
to target array. Pointer increment. Pop operator
6. If top!=-1 add remaining all operators in stack to target
array.
 Print the target array.
Postfix to Prefix
 struct: int top. char stack[max], target[max],
temp1[2], temp[2], str1[max], str2[max],
str3[max].
 Initialization i=0,top=-1, target array to empty.
 Convert: while( char scanned is !=‘\0’
1. If char scanned is ‘ ’,’\t’-> move forward.
2. If char scanned is *,/,%,+,-,**($,^)-> pop str2, pop
str3. temp1[0]=char scanned, temp[1]=‘\0’, copy
temp1 to str1, concatenate str1, st3 and then str1,
str2. push str1 on stack.
3. else temp[0]==char scanned, temp[1]=‘\0’, copy
temp1 to temp2. push temp2 to stack.
 Print the stack contents. 42$3*3-84/11+/+
Postfix to Infix

 pref