0% found this document useful (0 votes)
10 views

MODULE_1

Uploaded by

veena.s
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views

MODULE_1

Uploaded by

veena.s
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 177

INTRODUCTION

DATA STRUCTURES
BASIC TERMINOLOGY
DATA: Values or set of values
DATA ITEM:
• Single unit of values
• That are divided into sub items called
GROUP items
• Collection of data are frequently organized
into hierarchy of fields ,record and files
Entity ,Attribute and entity set
• Entity is something that has certain properties
(attributes) which may be assigned values.
Ex: Employee  entity
name age emp_id attributes
Rohit 34 e567
• Entities with similar attributes form an entity
set
Data Structures
• Logical or mathematical model of a particular
organization of data
• The choice of a particular model depends on 2
consideration
1. Rich enough in structure to mirror the actual
relationships of data in the real world
2. Simple enough that one can effectively
process the data when necessary
Classification of Data Structure
1.Primitive Data Structures: These are basic
structures that directly operate on machine-
level instructions.
Examples: Integer, Float, Char, Pointer
2. Non-Primitive Data Structures: These are
more complex structures built using primitive
data types
Arrays
• Linear array is a list of finite number n similar
data elements referenced respectively by a
set of n consecutive numbers.

STUDENT,SALES
Linked List
• A linked list is a linear data structure that
includes a series of connected nodes.
• each node stores the data and the address of
the next node.
• STACK: A Stack, also called a last-in-first-out ( LIFO )
system. It is a linear list in which insertions and
deletions cam take place only at one end called the top.
• QUEUE : A queue, also called a first-in-first out
(FIFO)system, is a linear list in which deletions
can take place only at one end of the list. The
“front” of the list, and insertions can take
place only at the other end of the list, the
“rear” of the tag.
TREES
• Reflects the hierarchical relationship between
various elements
Ex:Employee(e_id,name,address,age,sal)
• GRAPH : Data sometimes contain a
relationship between pairs of elements which
is not necessary hierarchical in nature.
DATA STRUCTURE OPERATIONS
• TRAVERSING : Accessing each record exactly once so
that certain items in the record may be processed.

• SEARCHING : Finding the location of the record with


a given key value or finding the locations of all
records which satisfy one or more conditions.

• INSERTING : Adding a new record to the structure.

• DELETING : Removing a record from the structure.


POINTERS
• A pointer is a variable which contains the
address in memory of another variable.
• The two most important operator used with
the pointer type are
& - The unary operator & which gives the
address of a variable
* - The indirection or dereference operator
* gives the content of the object pointed to by
a pointer.
Declaration
• int i, *pi;
Here, i is the integer variable and
pi is a pointer to an integer
pi = &i;
Here, &i returns the address of i and
assigns it as the value of pi
Void Pointer

• A pointer in a program that isn’t associated


with a data type is known as a void pointer
SYNTAX:
void *name_of_pointer;
Memory Management in C
• There are two types of memory
1. Static Memory
2. Dynamic Memory
• Static Memory Allocation: The memory is
allocated during compile-time.
• Dynamic Memory Allocation: process of
allocating or de-allocating memory blocks
during a program’s runtime.
Method Description

• .
malloc() Allocates a single block
of requested memory.
calloc() Allocates multiple
blocks of requested
memory
realloc() Reallocates the memory
occupied by malloc() or
calloc() functions
free() Frees the dynamically
allocated memory
malloc()
• used to dynamically allocate a single large block of memory
with the specified size.
• It returns a pointer of type void which can be cast into a
pointer of any form
Syntax :
ptr = (cast-type*) malloc(byte-size)
• doesn't initialize memory at execution time, so it has garbage
value initially.
• It returns NULL if memory is not sufficient.
• ptr holds the address of the first byte in the allocated memory
Example:
ptr = (int*) malloc(3 * sizeof(int));
calloc()
• allocate the specified number of blocks of
memory of the specified type
Syntax
ptr = (cast-type*)calloc(n, element-size);
• n is the no. of elements
• element-size is the size of each element
Example:
Ptr
= (float*) calloc(8, sizeof(float));
#include<stdio.h>
void main()
{
int *ptr, i,n;
printf(“enter value for n\n”);
scanf(“%d”,&n);
ptr=(int*)calloc(n,sizeof(int));
printf(“ enter n values\n”);
for (i=0;i<n;i++)
{
scanf(“%d”,ptr+i);
sum=sum+ *(ptr+i);
}
printf( “ The n values are\n”);
for(i=0;i<n;i++)
printf(“ %d\t”,*(ptr+i));
printf(“ sum=%d\n”,sum);
}
realloc() method

• change the memory allocation of a previously


allocated memory.
• re-allocation of memory maintains the already
present value and new blocks will be
initialized with the default garbage value.
Syntax: ptr = realloc(ptr, newSize);
free()
• de-allocate the memory..
• Syntax
free(ptr);
Structure
• is a user-defined data type
• collection of logically related elements of
same or different data types .
Syntax to Define a Structure in C

struct structure_name
{
data_type member1;
data_type member2;
.
.
data_type memeberN;
};
Example:
struct person
{
char name[20];
int age;
float salary
};
Declaring structure variable

1. Declaration of Structure Variables with Structure


Definition
struct structure_name
{
data_type member1;
data_type member2;
.
.
data_type memeberN;
}var1,var2…..varN;
Declaration of Structure Variables Separately

struct structure_name
{
data_type member1;
data_type member2;
.
.
data_type memeberN;
};
struct structure_name var1,var2,…….,varN;
Accessing members of the structure

There are two ways to access structure


members:
• By . (member or dot operator)
• By -> (structure pointer operator)
SYNTAX:
Structurevariable. Member
typedef
• The typedef is a keyword that is used to
provide existing data types with a new name.
• The C typedef keyword is used to redefine the
name of already existing data types.
Syntax
• typedef existing_name alias_name;
typedef struct

• typedef to define a new type name for a


structure. This can make your code more
readable and reduce redundancy.
Syntax:
typedef struct
{
// structure members // ...
} TypeName;
Example :
typedef struct
{
char name[50];
int age;
} Person;
void main()
{
Person P1;
}
1. Local variables are stored in an area called
___________
a) Heap
b) Permanent storage area
c) Free memory
d) Stack
Ans:d
2. Which of the following header files must
necessarily be included to use dynamic
memory allocation functions?
a) stdlib.h
b) stdio.h
c) memory.h
d) dos.h
Ans:d
Which of the following is an example for
non linear data type?

a) Tree
b) Array
c) Linked list
d) Queue

Ans: a
Queue data structure works on the
principle of ____________

a) Last In First Out (LIF0)


b) First In Last Out (FILO)
c) First In First Out (FIFO)
d) Last In Last Out (LILO)

Ans:c
If malloc() and calloc() are not type casted, the default return
type is _____

(a)void*
(b)void**
(c)int*
(d)char*

Ans: void*
Which of the following functions allocates multiple blocks of memory, each block of
the same size?

(a)malloc()
(b)realloc()
(c)calloc()
(d)free()

Ans: c
What is functionality of realloc() function

(a)Change the location of memory allocated by


malloc() or calloc().
(b)Reallocates memory deleted by free()
function.
(c)It is used to modify the size of the previously
allocated memory space.
(d)None of these
What is the output?void main()
{
int *ptr;
ptr = (int *)calloc(1,sizeof(int));
printf("%d\n",*ptr);
}
(a)0
(b)-1
(c)Error
(d)Null
SELF REFERENTIAL STRUCTURES
• Is one in which one or more of its components is a pointer to itself
Syntax:
struct structure_name
{
data_type variable1;
data_type variable1;
data_type variable1;
struct structure_name * pointer;
};
Ex:
struct list
{
char data;
struct list *link;
} item1,item2,item3;
UNION
• a user-defined data type in C language that can contain
elements of the different data types just like structure.
• unlike structures, all the members in the union are stored in
the same memory location
SYNTAX:
union unionName
{
data_type member1;
data_type member2;
.
.
data_type memeberN; ... } unionVar1, unionVar2, ...;
Example
union student
{
char name[20];
int usn;
}s1,s2;
ARRAYS

• an ordered set of similar data items.


• All the data items of an array are stored in
consecutive memory locations.
• The data items of an array are of same type and
each data items can be accessed using the same
name but different index value.

• An array is a set of pairs, <index, value >, such that


each index has a value associated with it. It can be
called as corresponding or a mapping
ADT Abstract Data Type
• It is a high-level description of a set of data
and the operations that can be performed on
that data, independent of the specific
implementation.
Array in C

• A one dimensional array in C is declared by


adding brackets to the name of a variable.
EXAMPLE:
int list[5], *plist[5];
Implementation:
• When the complier encounters an array declaration,
list[5], it allocates five consecutive memory locations.
Each memory is enough large to hold a single integer.
• The address of first element of an array is called Base
Address.
Ex: For list[5] the address of list[0] is called the base
address.
• If the memory address of list[i] need to compute by the
compiler, then the size of the int would get by sizeof (int),
then memory address of list[i] is as follows:

list[i] = α + i * sizeof (int)


Difference between
int *list1;
int list2[5];

(list2+i) is equal &list2[i] and *(list2+i) is equal


to list2[i].
How C treats an array when it is parameter to a function?

• All parameters of a C functions must be


declared within the function. As various
parameters are passed to functions, the name
of an array can be passed as parameter.
• The range of a one-dimensional array is
defined only in the main function since new
storage for an array is not allocated within
afunction
#include <stdio.h>
#define size 8
void printArray(int arr[], int n)
{
printf("Array Elements: ");
for (int i = 0; i < n; i++)
{
printf("%d ", arr[i]);
}}
int main()
{
int arr[size] = {12, 4, 5, 3, 7, 8, 11, 45};
printArray(arr, size);
return 0;
DYNAMICALLY ALLOCATED ARRAYS
One Dimensional Array:
int i, n, *list;
printf(“Enter the number of numbers to generate:”);
scanf(“%d”, &n);
if(n<1)
{
printf (“Improper value of n \n”);
}
list=(int *) malloc(n*sizeof(int))
Two Dimensional Arrays:
• C uses array-of-arrays representation to
represent a multidimensional array.
• The two dimensional arrays is represented
as a one-dimensional array in which each
element is itself a one-dimensional array
Example : int x[3][5];
• C find element x[i][j] by first accessing the
pointer in x[i].
• Where x[i] = α+ i* sizeof(int), which give the
address of the zeroth element of row i of the
array.
• Then adding j*sizeof(int) to this pointer ( x[i] )
, the address of the [j]th element of row i is
determined.
• X[i][j]=x[i]+j*sizeof(datatype)
#include<stdlib.h>
#include<stdio.h>
int main()
{
int **p,i,j;
int row = 5,col = 4;
p = (int **) malloc(row*sizeof(int *));
for(i=0;i<5;i++)
p[i] = (int *) malloc(col*sizeof(int));
/*assigning and printing 2d array*/
for(i=0;i<5;i++){
for(j=0;j<5;j++){
p[i][j] = i+j;
printf("%d ",p[i][j]);
}
printf("\n");
}
POLYNOMIALS

• A polynomial is a sum of terms, where each


term has a form ax^e , where x is the
variable, a is the coefficient and e is the
exponent.”
• Two example polynomials are:
A(x) =3x20 + 2x5+ 4
B(x) =x4+ 10x3+ 3x2+1
• The largest (or leading) exponent of a
polynomial is called its degree.
• Coefficients that are zero are not displayed.
• The term with exponent equal to zero does
not show the variable since x raised to a
power of zero is 1.
• Assume there are two polynomials,
A(x) = Σ ai xi and B (x) =Σ bixi

then:
• A(x) + B(x) = Σ (ai + bi) xi
Polynomial Representation

#define MAX-DEGREE 101


typedef struct
{
int degree;
float coef[MAX-DEGREE];
} polynomial;
polynomial a;
• Now if a is a variable and is of type polynomial
and n <MAX_DEGREE,
• the polynomial A(x) = Σai xi would be
represented as:
a.degree = n
a.coef[i] = an-i , 0 ≤ i ≤ n
d =Zero()
while (! IsZero(a) && ! IsZero(b))
do {
switch COMPARE(LeadExp(a), LeadExp(b))
{
case -1:
d = Attach(d, Coef(b,LeadExp(b)) , LeadExp(b)) ;
b = Remove(b, LeadExp(b));
break;
case 0:
sum =Coef( a,LeadExp(a))+ Coef( b,LeadExp(b));
if (sum!=0)
{
d=Attach(d,sum,LeadExp(a));
a = Remove(a,Lead—Exp(a));
b = Remove(b,LeadExp(b));
}
break;
case 1:
d = Attach(d, Coef(a,LeadExp(a)) ,
LeadExp(a)) ;
a= Remove(a, LeadExp(a));
}
}
insert any remaining terms of a or b into d
MAX_TERMS 100 /*size of terms array*/
typedef struct
{
float coef;
int expon;
} polynomial;
polynomial terms[MAX-TERMS];
int avail = 0;
• polynomials are stored in the array terms.
• The index of the first term of A and B is given
by starta and startb, respectively,
• while finisha and finishb give the index of the
last term of A and B.
• The index of the next free location in the array
is given by avail
void padd(int starta, int finisha, int startb, int
finishb,int* startd, int* finishd)
{
float coefficient;
*startd = avail;
while (starta <= finisha && startb <= finishb)
{
switch
(COMPARE(terms[starta].expon,terms[startb].
expon))
{
case 0: coefficient = terms[starta].coef +
terms[startb].coef;
if (coefficient != 0.0)
{
attach(coefficient, terms[starta].expon);

}
starta++;
startb++;
break;
case -1:
attach(terms[startb].coef, terms[startb].expon);
startb++;
break;
case 1:
attach(terms[starta].coef, terms[starta].expon);
starta++;
break;
}
}
for (; starta <= finisha; starta++)
{
attach(terms[starta].coef, terms[starta].expon);
}
for (; startb <= finishb; startb++)
{
attach(terms[startb].coef, terms[startb].expon);
}
*finishd = avail - 1;
}
void attach(float coefficient, int exponent)

{
if (avail >=MAX_TERMS)
{
printf( "Too many terms in the polynomial\n");
}
terms[avail].coef = coefficient;
terms[avail++].expon = exponent;
}
Sparse Matrix
• a matrix that contains a few non-zero
elements
Sparse matrix representation
• we can characterize uniquely any element
within a matrix by using the triple
<row,col,value>
• An array of triples is used to represent a
sparse matrix
• Sparsematrix create(maxrows,maxcol)::=
typdef struct
{
int row,
int col,
int value
}term;
term a[max_terms];
Transposing a Matrix
• each element in a[i][j] in the original matrix
becomes element b[j][i] the transpose matrix
• algorithm for transposing a matrix:
Algorithm:
for each row i
take element <i,j,value>and store it as element
<j,i,value>of the transpose;
• if we process the original matrix by the row
indices we will not know exactly where to place
element in the transpose matrix until we have
processed all the elements that precede it
Algorithm
for all elements in column j
take element <i,j,value>and store it as element
<j,i,value> of the transpose
void transpose(term a[], term b[]) {
int n, i, j, currentb;

// Extract the total number of non-zero elements in the matrix


n = a[0].value;

// Set the dimensions of the transposed matrix b


b[0].row = a[0].col;
b[0].col = a[0].row;
b[0].value = n;

currentb = 1; // Initialize the current position in b

// Loop through columns in the original matrix a


for (i = 0; i < a[0].col; i++) {
// Loop through elements in the current column of a
for (j = 1; j <= n; j++) {
// Check if the element is in the current column
if (a[j].col == i) {
// If yes, add the transposed element to b
b[currentb].row = a[j].col;
b[currentb].col = a[j].row;
b[currentb].value = a[j].value;
currentb++;
}
}
}
}
FAST TRANSPOSE
void fast_transpose(term a[], term b[])
{
int row_terms[MAX_COL];
int starting_pos[MAX_COL];
int i, j;
int num_cols =
a[0].col
int num_terms =
a[0].value;
// Set properties of the result matrix b[0]
b[0].row =
num_cols;
b[0].col =
a[0].row;
b[0].value =
num_terms;
if (num_terms > 0)
{
(i = 0; i < MAX_COL; i++)
{
row_terms[i] = 0;
}
// Count the number of terms in each column of
the original matrix
for (i = 1; i <= num_terms; i++)
{
row_terms[a[i].col]++;
}
// Compute the starting position of each column
in the result matrix
starting_pos[0] = 1;
for (i = 1; i < num_cols; i++)
{
starting_pos[i] =
starting_pos[i - 1]
+
row_terms[i - 1];
}
// Perform the transpose
for (i = 1; i <= num_terms; i++)
{
j = starting_pos[a[i].col]++;
b[j].row = a[i].col;
b[j].col = a[i].row;
b[j].value = a[i].value;
}}
STRING
• strings as character arrays terminated with the
null character \0
Ex:
• #define MAX—SIZE 100
• char s[MAX-SIZE] ={Dog};
• char t[MAX-SIZE] ={House};
1.char *strcat(char *dest, char *src)
concatenate dest and strings; return result in
dest
char *dest = "Hello, ";
char *src = "world";
strcat(dest, src);

Output :
Hello, world
2.char *strncat(char *dest, char *src, int
n):concatenate dest and n characters from src; return
result in dest

char *dest = "Welcome, ";


const char *src = “john”;
strncat(dest, src, 3);
Result:
Welcome, Joh
3.char *strcmp(char *str1, char *str2)

4.char *strncmp(char *strl, char *str2, int n)

5.char *strcpy(char *dest, char *src)


char *dest;
char *src = "Hello, World!";
Output:
dest: Hello, World!";
Size_t strlen(char *s):return the length of a
s
• char *strchr(char *s, int c):return pointer to
the first occurrence of c in s; return NULL if
not present
Ex:
char *str = "Hello, World!";
char target = 'W';
strchr(str, target);
Output:Character 'W' found at position: 7
char *strncpy(char *dest, char *src, int n):copy
n characters from src string into dest; return
dest;
Example:
char dest[20];
const char *src = "Hello, World!";
strncpy(dest, src, 10);
char *strncpy(char *dest, char *src, int n)

return pointer to last occurrence of c in 5; return


NULL if not present
char *str = "Hello, World!";
char target = 'W';
char *result = strchr(str, target);
Output:
Character 'W' found at position: 7
char *strchr(char *s, char c):return pointer to the
first occurrence of c in s; return NULL if not present

char *str = "Hello, World!";


char target = 'W';
strchr(str, target);
Output:
Character 'W' found at position: 7
char *strrchr(char *s, char c)
char *str = "Hello, World!";
char target = 'o';
Find the last occurrence of 'o' in the string char
*result = strrchr(str, target);
strstr()

• This function searches for the first occurrence


of a substring within a string.
• Ex:
• const char *str = "Hello, World!";
• const char *pattern = "World";
char *result = strstr(str, pattern);
String insertion function
void strnins(char *s, char *t, int i)
{
char temp[MAX_SIZE];
if (i < 0 || i > strlen(s))
{
printf( "Position is out of bounds\n");
exit(1);
}
if (strlen(s) == 0)
{
strcpy(s, t);
}
else
if (strlen(t) > 0)
{
strncpy(temp, s, i);
temp[i] = '\0';
strcat(temp, t); strcat(temp, s + i);
strcpy(s, temp);
}
}
Pattern matching by checking end indices
first
int nfind(char *string, char *pat)
{
int i, j, start = 0;
int lasts = strlen(string) - 1;
int lastp = strlen(pat) - 1;
int endmatch = lastp;
for (i = 0; endmatch <= lasts; endmatch++, start++)
{
if (string[endmatch] == pat[lastp])
{
for (j = 0, i = start; j < lastp && string[i] == pat[j]; i++,
j++)
;
if (j == lastp)
return start;
}
return —1;
}
THE STACK
• A stack is an ordered list in which insertions
and deletions are made at one end called the
top
• Given a stack S = {a0,a1……,an-1} we say that
a0 is the bottom element, an-1is the top
element, and ai is on top of ai-1, 0 < i < n.
• Since the last element inserted into a stack is
the first element removed, a stack is also
known as a Last-In-first-Out (LlFO) list.
System stack
• used by a program at run-time to process function
calls.
• Whenever a function is invoked, the program creates
a structure, referred to as an activation record or a
stack frame, and places it on top of the system stack.
• activation record for the invoked function contains
only a pointer to the previous stack frame and a
return address.
• The previous stack frame pointer points to the stack
frame of the invoking function, while the return
address contains the location of the statement to be
executed after the function terminates
• only one function executes at any given time,
the function whose stack frame is on top of
the system stack is chosen.
• If this function invokes another function, the
local variables, except those declared static,
and the parameters of the invoking function
are added to its stack frame.
stack CreateS(maxStackSize)::=
#define MAX_STACK_SIZE 100
typedef struct {
int key;
}element;
element stack[MAX_STACK_SIZE];
int top=-1;
Boolean IsEmpty(Stack)::=
top<0;
Boolean IsFull(Stack)::=
top>=max_size-1
void push(element item)
{
if(top>=max_stack_size-1)
stackfull();
Stack[++top];
}
Element pop()
{
If(top==-1)
return stackEmpty()
return s[top--];
}
void stackfull()
{
Printf(“stack is full,cannot add element”)
}
Infix to postfix conversion
5 3 2*+4–5+
A=12

7 4 3 * 1 5 + / *
A=14
6 2 / 3 - 4 2 * +
A=8
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include <string.h>
#define SIZE 50 /* Size of Stack */

int s[SIZE], top = -1;


void main()
{
char expr[50];

printf("Enter postfix expression: ");


scanf("%s", expr);

for (int i = 0; expr[i]!=‘\0’; i++) {


peval(expr[i]);
}

printf("Result: %d\n", pop());


}
void peval(char ch)
{
if (isdigit(ch))
{
push(ch - '0');
return;
}

int op2 = pop();


int op1 = pop();
switch(ch)
{
case '+':
push(op1 + op2);
break;

case '-':
push(op1 - op2);
break;
• case '*':
push(op1 * op2);
break;

case '/':
push(op1 / op2);
break;

case '%':
push(op1 % op2);
break;
case '^':
push(pow(op1, op2));
break;

default:
printf("Invalid operator\n");
}
}
void push(int elem)
{
s[++top] = elem;
}

int pop()
{
return s[top--];
}
Stacks using dynamic arrays
• The static stack implementation(MAX SIZE)
can be limited because the size of the array is
defined at compile time. If the stack exceeds
this size, it will overflow.
• The solution is to use dynamic memory
allocation. Instead of defining a fixed size,
you dynamically allocate memory for the
stack and resize the array when the stack
is full.
THE QUEUE
• A queue is an ordered list in which all
insertions take place at one end and all
deletions take place at the opposite end.
Given a queue Q = (a0,a1……,an-1)
a0 is FRONT element
an-1 is REAR element
INSERTION –REAR END
DELETION- FRONT END
Types of Queues

1. Simple Queue
2. Circular Queue
3. Priority Queue
4. Dequeue (Double Ended Queue)
circular queue
• A circular queue exhibits similar characteristics
to that of a simple queue, with the additional
property of joining the front end to the rear
end.
• It is also known as the ring buffer.
Double Ended Queue

• A Double-ended Queue, or Deque, is a


different type of queue where enqueue
(insertion) and dequeue (deletion) operations
are performed at both the ends, i.e., the rear-
end (tail) and the front-end (head)
Queue CreateQ(max-queue-size) ::=
#define MAX-QUEUE—SIZE 100
typedef struct
{
int key;
} element;
element queue[MAX—QUEUE—SIZE];
int rear = -1;
int front = -1 ;
Boolean IsEmptyQ(queue) ::=
front ==rear
• Boolean IsFull(queue) ::=
rear == MAX—QUEUE—SIZE-1
Enqueue (inserting value)
int addq(int rear, element item)
{
if ( rear ==MAX-QUEUE-SIZE-1)
{
Queue_full() ;
return -1;

}
return queue[++ rear]
}
Dequeue (deletion from queue)
element deleteq(int {int front, int rear)
{
if (front == rear)
return queue_empty();
return queue[front++];
}
• only one function executes at any given time,
the function whose stack frame is on top of
the system stack is chosen.
• If this function invokes another function, the
local variables, except those declared static,
and the parameters of the invoking function
are added to its stack frame.
Stacks using dynamic arrays
• The static stack implementation (with a fixed
MAX_STACK_SIZE) can be limited because you
must define the maximum size at compile
time. If the stack exceeds this size, it will
overflow.
• The solution is to use dynamic memory
allocation. Instead of defining a fixed size, you
dynamically allocate memory for the stack and
resize the array when the stack is full.
int *stack;
int capacity;
int top;
void createStack(int initialCapacity)
{
stack = (int *)malloc(initialCapacity *sizeof(int));
capacity = initialCapacity;
top = -1;
}
int isEmpty()
{
return top < 0;
}
int isFull()
{
return top >= capacity - 1;
}
void stackFull()
{
printf("Stack is full. Doubling the stack
capacity...\n");
capacity *= 2;
stack = realloc(stack, capacity * sizeof(int))
}
void push(int key)
{
if (isFull())
{
stackFull();
}
top++;
stack[top] = key
printf("Pushed %d onto the stack.\n", key);
}
MULTIPLE STACKS AND QUEUES
• The representations of a single stack or a
single queue. In both cases, we have seen that
it is possible to obtain efficient sequential
representations.
• Let memory[MEMORY-SIZE] is a single
dimensional array to implement multiple
stacks
• Two-Stack Representation :
• one stack at the beginning (memory[0]),
• The second stack at the end
(memory[MEMORY-SIZE - 1]).
• The stacks grow toward each other
• Multiple Stacks Representation:
Assuming that we have n stacks , to
represent n stacks is to divide the available
memory into n equal (or proportional) segments
based on the expected usage of each stack.
For example,
• if the total memory is MEMORY-SIZE
• we have n stacks,
• we could allocate MEMORY-SIZE/n for each
stack
• Given a memory size of 12 and 3 stacks to
manage
• Let i refers to the stack numbers of the n
stacks
1.boundary[i], 0<=i<=MAX_STACKS
• This array holds the index of the boundary just
before the first element of stack i
• Points to the position immediately to the left
of the bottom element of stack i
• top[i]: 0<=i<=MAX_STACKS
This array holds the current top index of stack i,
which points to the last (topmost) element of
that stack.
Relevant Declaration
#define MEMORY_SIZE 100
#define MAX_STACKS 10
int memory[MEMORY_SIZE];
int top[MAX_STACKS];
int boundary[MAX_STACKS ];
int n;
• To divide the array into roughly equal
segments we use the following code:
top[0] = boundary[0]; = -1;
for (int j = 1; j < n; j++)
top[j]=boundary[j]=(MEMORY_SIZE/n)*j-1;
boundary[n]= MEMORY_SIZE-1
Push function
void push(int i, int item)
{
if (top[i] == boundary[i+1])

stackFull(i);
memory[++top[i]] = item;
}
Delete an item from i th stack
int pop(int i)
{
if (top[i] == boundary[i])
stack_empty(i);
return memory[top[i]--];
}
Circular Queues using dynamic arrays
• start with an array of a certain capacity, say 4.
In the example, the queue is shown with 4
elements, and the rear index is just before the
front index due to the circular nature
• you add an element, the rear index is
incremented as rear = (rear + 1) % capacity;.
This operation ensures that the index wraps
around if it reaches the end of the array
(circular behavior).
• If the rear index becomes equal to the front
index, the queue is full, and need to increase
the size of the array using realloc
• Doubling the Capacity:
• When the queue is full, the capacity is
doubled by creating a new array, newQueue,
with double the size of the old one.
Rearranging Elements:
• The queue's elements are rearranged in the new
array to maintain the correct order:
• The second segment of the queue (elements from
queue[front + 1] to queue[capacity-1]) is copied to the
beginning of the new array.
• The first segment of the queue (elements from
queue[0] to queue[rear]) is copied to the end of the
new array.
• This ensures that the circular order is maintained
even after the array's capacity has been increased.
void queueFull()
{

int *newQueue;
newqueue=(int*) malloc(2 * capacity *sizeof(*queue));
int start = (front + 1) % capacity;
if (start < 2)
copy(queue + start, queue + start + capacity,
newQueue);
else
{

copy(queue + start, queue + capacity, newQueue);


copy(queue, queue + rear + 1, newQueue + capacity
- start);
}
/* switch to newQueue*/
front = 2 * capacity - 1;
rear = capacity - 2;
capacity *= 2;
free(queue);
queue = newQueue;
}

You might also like