0% found this document useful (0 votes)
21 views48 pages

DS Lab Manual

Uploaded by

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

DS Lab Manual

Uploaded by

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

DEPARTMENT OF

CSE(AI&ML)

Lab Manual

DATA STRUCTURES USING C LAB


(BCS 351)

Student Copy

INDERPRASTHA ENGINEERING
COLLEGE, GHAZIABAD
(63, Site-IV, Sahibabad, Affiliated to AKTU University, Lucknow)
INDERPRASTHA ENGINEERING COLLEGE, GHAZIABAD
Department of CSE (AI&ML)
LIST OF EXPERIMENTS:
S.No Experiments/Lab Page No
1 Write programs to implement the following search algorithms in an array. 1-3
a) Linear search
b) Binary search

2 Write C programs for following sorting algorithms. 4-9


a) Insertion Sort
b) Bubble Sort
c) Selection Sort
d) Heap Sort

3 Write C programs for the following sorting algorithms (Recursive). 10-13


a) Quick Sort
b) Merge Sort

4 Write a program for array implementation of stack. 14-17

5 Write a program for implementation of queue using array. 18-22

6 Write a program to implement Circular Queue using array. 23-27

7 Write a C program to implement Stack using Linked List. 28-30

8 Write a C program to implement Queue using Linked List. 31-33

9 Write a C program to implement Circular Queue using Linked List. 34-37

10 Write C programs to implement 38-46


a) traversal operations in a binary tree.
b) Insertion & deletion operations in a binary search tree.
PROGRAM – 01
1.1 Objective: Write programs to implement the following search algorithms in an array:
a) Linear search
b) Binary search
1.2 Linear Search/ Sequential search
Theory
Searching is the process of finding some particular element in the list. If the element is present in the
list, then the process is called successful, and the process returns the location of that element;
otherwise, the search is called unsuccessful.

It is the simplest searching algorithm. In Linear search, we simply traverse the list completely
and match each element of the list with the item whose location is to be found. If the match is
found, then the location of the item is returned; otherwise, the algorithm returns NULL. It is
widely used to search an element from the unordered list.
Code
#include <stdio.h>
int main()
{
int array[100], search, c, n;
printf("Enter number of elements in array\n");
scanf("%d", &n);
printf("Enter %d integer(s)\n", n);
for (c = 0; c < n; c++)
scanf("%d", &array[c]);
printf("Enter a number to search\n");
scanf("%d", &search);
for (c = 0; c < n; c++)
{
if (array[c] == search) /* If required element is found */
{
printf("Element iis present at %d location of the array\n", search, c+1);
break;
}
}
if (c == n)
printf("Element isn't present in the array.\n", search);
return 0;
}

1
Output of program

Complexity: O(n)
1.3 Binary search
Theory
Binary search follows the divide and conquer approach in which the list is divided into two
halves. It is applied on the sorted array or list. We first compare the value with the elements
in the middle position of the array. If the value is matched, then we return the value. If the
value is less than the middle element, then it must lie in the lower half of the array and if it's
greater than the element then it must lie in the upper half of the array. We repeat this
procedure on the lower (or upper) half of the array.
Code
#include <stdio.h>
int main()
{
int c, first, last, middle, n, search, array[100];
printf("Enter number of elements\n");
scanf("%d", &n);
printf("Enter %d integers\n", n);
for (c = 0; c < n; c++)
scanf("%d", &array[c]);
printf("Enter value to find\n");
scanf("%d", &search);
first = 0;
last = n - 1;
middle = (first+last)/2;

while (first <= last) {


if (array[middle] < search)
first = middle + 1;
else if (array[middle] == search) {
printf("%d found at location %d.\n", search, middle+1);
break;
}
else
last = middle - 1;
middle = (first + last)/2;
}
if (first > last)
printf("Not found! %d isn't present in the list.\n", search);
return 0;
}

2
Output

Complexity: O(log n)

3
PROGRAM -02

2.1 Objective: Write C programs for following sorting algorithms:


a) Insertion Sort
b) Bubble Sort
c) Selection Sort
d) Heap Sort

2.2 Insertion sort


Theory

It is an sorting algorithm in which first element in the array is assumed as sorted. Then each
element in the array is checked with the previous elements, resulting in a growing sorted
output list. With each iteration, the sorting algorithm removes one element at a time and finds
the appropriate location within the sorted array and inserts it there. The iteration continues
until the whole list is sorted.

Code

#include<stdio.h>
#include<conio.h>

void main()
{
int i, j,n,key,arr[20];
printf("Enter number of elements to use:");
scanf("%d",&n);
printf("Enter %d elements: ",n);

for(i=0;i<n;i++)
scanf("%d",&arr[i]);
for(i=1;i<n;i++){
key=arr[i];
j=i-1;
while((key<arr[j])&&(j>=0)){
arr[j+1]=arr[j];
j=j-1;
}
arr[j+1]=key;
}
printf("After sorting array elements are-\n ");
for(i=0;i<n;i++)
printf(" %d",arr[i]);
getch();
}

4
Output

Complexity: O(n2)

2.3 Bubble sort

Theory

Bubble sort is a sorting algorithm which is also called comparison-based algorithm in


which each pair of adjacent elements is compared and the elements are swapped if they are
not in order. Although it is simple to use, it is primarily used as an educational tool because
the performance of bubble sort is poor in the real world. It is not suitable for large data sets.

Complexity: O(n2)
Code

#include<stdio.h>
void print(int a[], int n) //function to print array elements
{
int i;
for(i = 0; i < n; i++)
{
printf("%d ",a[i]);
}
}
void bubble(int a[], int n) // function to implement bubble sort
{
int i, j, temp;
for(i = 0; i < n; i++)
{
for(j = i+1; j < n; j++)
{
if(a[j] < a[i])
{
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
}
void main ()
{
int i, j,temp;
int a[5] = { 10, 35, 32, 13, 26};
int n = sizeof(a)/sizeof(a[0]);
printf("Before sorting array elements are - \n");

5
print(a, n);
bubble(a, n);
printf("\nAfter sorting array elements are - \n");
print(a, n);
}
Output:

2.4 Selection sort


Theory
Selection sort is an sorting algorithm in which the array is divided into sorted array and
unsorted array. The smallest element is selected from the unsorted array and placed at the
first position of sorted array. Again, smallest element is selected from unsorted array and
placed at the second position of sorted array. The process continues until the array is entirely
sorted.
Code
#include <stdio.h>
void selection(int arr[], int n)
{
int i, j, small;
for (i = 0; i < n-1; i++) // One by one move boundary of unsorted subarray
{
small = i; //minimum element in unsorted array
for (j = i+1; j < n; j++)
if (arr[j] < arr[small])
small = j;
int temp = arr[small]; // Swap the minimum element with the first element
arr[small] = arr[i];
arr[i] = temp;
}
}
void printArr(int a[], int n) /* function to print the array */
{
int i;
for (i = 0; i < n; i++)
printf("%d ", a[i]);
}
int main()
{
int a[] = { 12, 31, 25, 8, 32, 17 };
int n = sizeof(a) / sizeof(a[0]);
printf("Before sorting array elements are - \n");
printArr(a, n);
selection(a, n);
printf("\nAfter sorting array elements are - \n");

6
printArr(a, n);
return 0;
}

Output:

Complexity: O(n2)

2.5 Heap sort

Theory

A heap is a complete binary tree. A binary tree is a tree in which the node can have utmost
two children. A complete binary tree is a binary tree in which all the levels except the last
level, i.e., leaf node, should be completely filled.
Heapsort is an in-place sorting algorithm. Heapify is the process of creating a heap data
structure from a binary tree represented using an array. It is used to create Min-Heap or Max-
heap. Start from the first index of the non-leaf node whose index is given by n/2 – 1.

Follow the given steps to solve the problem:

● Build a max heap from the input data.


● The maximum element is stored at the root of the heap. Replace it with the last item of
the heap followed by reducing the size of the heap by 1. Finally, heapify the root of the
tree.
● Repeat step 2 while the size of the heap is greater than 1.

Code

#include <stdio.h>
/* function to heapify a subtree. Here 'i' is the
index of root node in array a[], and 'n' is the size of heap. */
void heapify(int a[], int n, int i)
{
int largest = i; // Initialize largest as root
int left = 2 * i + 1; // left child
int right = 2 * i + 2; // right child
// If left child is larger than root
if (left < n && a[left] > a[largest])
largest = left;
// If right child is larger than root
if (right < n && a[right] > a[largest])
largest = right;
// If root is not largest

7
if (largest != i) {
// swap a[i] with a[largest]
int temp = a[i];
a[i] = a[largest];
a[largest] = temp;
heapify(a, n, largest);
}
}
/*Function to implement the heap sort*/
void heapSort(int a[], int n)
{
for (int i = n / 2 - 1; i >= 0; i--)
heapify(a, n, i);
// One by one extract an element from heap
for (int i = n - 1; i >= 0; i--) {
/* Move current root element to end*/
// swap a[0] with a[i]
int temp = a[0];
a[0] = a[i];
a[i] = temp;
heapify(a, i, 0);
}
}
/* function to print the array elements */
void printArr(int arr[], int n)
{
for (int i = 0; i < n; ++i)
{
printf("%d", arr[i]);
printf(" ");
}
}

int main()
{
int a[] = {48, 10, 23, 43, 28, 26, 1};
int n = sizeof(a) / sizeof(a[0]);
printf("Before sorting array elements are - \n");
printArr(a, n);
heapSort(a, n);
printf("\nAfter sorting array elements are - \n");
printArr(a, n);
return 0;
}

8
Output

Complexity: O(n log n)

9
PROGRAM -03

3.1 Objective: Write C programs for the following sorting algorithms (Recursive).
a) Quick Sort
b) Merge Sort
3.2 Quick sort
Theory
This algorithm follows the divide and conquer approach. It picks an element as pivot and then
partitions the given array around the picked pivot element. In quick sort, a large array is
divided into two arrays in which one holds values that are smaller than the specified value
(Pivot), and another array holds the values that are greater than the pivot. After that, the left
and right sub-arrays are also partitioned using the same approach. It will continue until the
single element remains in the sub-array.
Quick sort is the widely used sorting algorithm as it is a faster and highly efficient sorting
algorithm.
Code
#include <stdio.h>
/* function that consider last element as pivot,
place the pivot at its exact position, and place
smaller elements to left of pivot and greater
elements to right of pivot. */

int partition (int a[], int start, int end)


{
int pivot = a[end]; // pivot element
int i = (start - 1);

for (int j = start; j <= end - 1; j++)


{
// If current element is smaller than the pivot
if (a[j] < pivot)
{
i++; // increment index of smaller element
int t = a[i];
a[i] = a[j];
a[j] = t;
}
}
int t = a[i+1];
a[i+1] = a[end];
a[end] = t;
return (i + 1);
}

10
/* function to implement quick sort */
void quick(int a[], int start, int end) /* a[] = array to be sorted, start = Starting index, end = En
ding index */
{
if (start < end)
{
int p = partition(a, start, end); //p is the partitioning index
quick(a, start, p - 1);
quick(a, p + 1, end);
}
}

/* function to print an array */


void printArr(int a[], int n)
{
int i;
for (i = 0; i < n; i++)
printf("%d ", a[i]);
}
int main()
{
int a[] = { 24, 9, 29, 14, 19, 27 };
int n = sizeof(a) / sizeof(a[0]);
printf("Before sorting array elements are - \n");
printArr(a, n);
quick(a, 0, n - 1);
printf("\nAfter sorting array elements are - \n");
printArr(a, n);
return 0;
}

Output

Complexity: O(n2)
3.3 Merge sort
Theory
We can think of it as a recursive algorithm that continuously splits an array in half until it
cannot be further sub divided. This means that if the array becomes empty or has only one
element left, the dividing will stop (base case to stop the recursion). Finally, when both the

11
halves are sorted, the merge operation is applied. Merge operation is the process of taking
two smaller sorted arrays and combining them to eventually make a larger sorted one.
Code
#include <stdio.h>
/* Function to merge the subarrays of a[] */
void merge(int a[], int beg, int mid, int end)
{
int i, j, k;
int n1 = mid - beg + 1;
int n2 = end - mid;
int LeftArray[n1], RightArray[n2]; //temporary arrays

/* copy data to temp arrays */


for (int i = 0; i < n1; i++)
LeftArray[i] = a[beg + i];
for (int j = 0; j < n2; j++)
RightArray[j] = a[mid + 1 + j];

i = 0; /* initial index of first sub-array */


j = 0; /* initial index of second sub-array */
k = beg; /* initial index of merged sub-array */

while (i < n1 && j < n2)


{
if(LeftArray[i] <= RightArray[j])
{
a[k] = LeftArray[i];
i++;
}
else
{
a[k] = RightArray[j];
j++;
}
k++;
}

while (i<n1)
{
a[k] = LeftArray[i];
i++;
k++;
}

while (j<n2)

12
{
a[k] = RightArray[j];
j++;
k++;
}
}
void mergeSort(int a[], int beg, int end)
{
if (beg < end)
{
int mid = (beg + end) / 2;
mergeSort(a, beg, mid);
mergeSort(a, mid + 1, end);
merge(a, beg, mid, end);
}
}

void printArray(int a[], int n)


{
int i;
for (i = 0; i < n; i++)
printf("%d ", a[i]);
printf("\n");
}
int main()
{
int a[] = { 12, 31, 25, 8, 32, 17, 40, 42 };
int n = sizeof(a) / sizeof(a[0]);
printf("Before sorting array elements are - \n");
printArray(a, n);
mergeSort(a, 0, n - 1);
printf("After sorting array elements are - \n");
printArray(a, n);
return 0;
}
Output

Complexity: O(n log n)

13
PROGRAM -04
4.1 Objective: Write a program for array implementation of stack.
4.2 Theory
Stack is a linear data structure that follows the LIFO (Last In First Out) principle, where it
performs all operations. It performs insertion and deletion operations on the stack from only
one end called the top of stack. You can perform the implementation of the stack in memory
using two data structures: using array and using linked-list.
Possible stack operations are:
● push() to insert an element into the stack
● pop() to remove an element from the stack
● top() Returns the top element of the stack.
● isEmpty() returns true if stack is empty else return false

4.3 Code
#include<stdio.h>
int stack[100], choice, n, top, x, i ;
void push(void);
void pop(void);
void display(void);
int main()
{
//clrscr();
top=-1;
printf("\n Enter the size of STACK[MAX=100]:");
scanf("%d",&n);
printf("\n\t STACK OPERATIONS USING ARRAY");
printf("\n\t--------------------------------");
printf("\n\t 1.PUSH\n\t 2.POP\n\t 3.DISPLAY\n\t 4.EXIT");
do
{
printf("\n Enter the Choice:");
scanf("%d",&choice);
switch(choice)
{

14
case 1:
{
push();
break;
}
case 2:
{
pop();
break;
}
case 3:
{
display();
break;
}
case 4:
{
printf("\n\t EXIT POINT ");
break;
}
default:
{
printf ("\n\t Please Enter a Valid Choice(1/2/3/4)");
}
}
}
while(choice!=4);
return 0;
}
void push()

15
{
if(top>=n-1)
printf("\n\tSTACK is over flow");
else
{
printf(" Enter a value to be pushed:");
scanf("%d",&x);
top++;
stack[top]=x;
}
}
void pop()
{
if(top<=-1)
printf("\n\t Stack is under flow");
else
{
printf("\n\t The popped elements is %d",stack[top]);
top--;
}
}
void display()
{
if(top>=0)
{
printf("\n The elements in STACK \n");
for(i=top; i>=0; i--)
printf("\n%d",stack[i]);
printf("\n Press Next Choice");
}

16
else
{
printf("\n The STACK is empty");
}
}
4.4 Output
Enter the size of STACK[MAX=100]:10

STACK OPERATIONS USING ARRAY


--------------------------------
1.PUSH
2.POP
3.DISPLAY
4.EXIT
Enter the Choice:1
Enter a value to be pushed:12

Enter the Choice:1


Enter a value to be pushed:24

Enter the Choice:1


Enter a value to be pushed:98

Enter the Choice:3

The elements in STACK

98
24
12
Press Next Choice
Enter the Choice:2

The popped elements is 98


Enter the Choice:3

The elements in STACK

24
12
Press Next Choice
Enter the Choice:4

EXIT POINT

17
PROGRAM -05
5.1 Objective: Write a program for implementation of queue using array.

5.2 Theory
Queue is an abstract data structure, somewhat similar to stacks. But unlike stacks, a queue is
open at both its ends. Insertion takes place from the rear end of the queue and deletion from
the front end of the queue. Queue follows First-In-First-Out methodology, i.e., the data item
stored first will be accessed first.
Operations on Queue data structure:
● enqueue() − add (store) an item into the queue.
● dequeue() − remove (access) an item from the queue.
● isfull() -- check for the rear pointer. If it reaches MAXSIZE, queue is full.
● isempty() -- check for the front pointer. If it is less than MIN or 0, queue is empty.
5.3 Code

#include<stdio.h>
#include<stdlib.h>
#define maxsize 5
void insert();
void delete();
void display();
int front = -1, rear = -1;
int queue[maxsize];
void main ()
{
int choice;
while(choice != 4)
{
printf("\n*****************Main Menu**************\n");
printf("\n1.insert an element\n2.Delete an element\n3.Display the queue\n4.Exit\n");
printf("\nEnter your choice ?");
scanf("%d",&choice);
switch(choice)

18
{
case 1:
insert(); break;
case 2:
delete(); break;
case 3:
display(); break;
case 4:
exit(0); break();
default:
printf("\nEnter valid choice??\n");
}
}
}
void insert()
{
int item;
printf("\nEnter the element\n");
scanf("\n%d",&item);
if(rear == maxsize-1)
{
printf("\nOVERFLOW\n");
return;
}
if(front == -1 && rear == -1)
front = rear = 0;
else
rear = rear+1;
queue[rear] = item;
printf("\nValue inserted ");

19
}
void delete()
{
int item;
if (front == -1 || front > rear)
{
printf("\nUNDERFLOW\n");
return;
}
else
{
item = queue[front];
if(front == rear)
{
front = -1;
rear = -1 ;
}
else
{
front = front + 1;
}
printf("\nvalue deleted ");
}
}
void display()
{
int i;
if(rear == -1)
printf("\nEmpty queue\n");
else

20
{ printf("\nprinting values .....\n");
for(i=front;i<=rear;i++)
{
printf("\n%d\n",queue[i]);
}} }
5.4 Output
*************Main Menu**************
1. insert an element
2.Delete an element
3.Display the queue
4.Exit

Enter your choice ?1


Enter the element
123
Value inserted

*************Main Menu**************

1.insert an element
2.Delete an element
3.Display the queue
4.Exit

Enter your choice ?1


Enter the element
90
Value inserted

21
*************Main Menu**************
1.insert an element
2.Delete an element
3.Display the queue
4.Exit

Enter your choice ?2


value deleted
*************Main Menu**************
1.insert an element
2.Delete an element
3.Display the queue
4.Exit
Enter your choice ?3
printing values .....
90
*************Main Menu**************
1.insert an element
2.Delete an element
3.Display the queue
4.Exit
Enter your choice ?4

22
PROGRAM -06
6.1 Objective: Write a program to implement Circular Queue using array.
6.2 Theory
A Circular Queue is a special version of queue where the last element of the queue is
connected to the first element of the queue forming a circle. The operations are performed
based on FIFO (First In First Out) principle. But instead of ending the queue at the last
position, it again starts from the first position after the last, hence making the queue behave
like a circular data structure. Deletions and insertions can only be performed at front and rear
end respectively just as in queue.
Implementation of a linear queue brings the drawback of memory wastage. When rear pointer
reaches the MaxSize of a queue, there might be a possibility that after a certain number of
dequeue() operations, it will create an empty space at the start of a queue. this newly created
empty space can never be re-utilized as the rear pointer reaches the end of a queue. Hence,
circular queue was introduced to overcome this limitation.

Operations On A Circular Queue:

1. Enqueue- adding an element into the queue.


2. Dequeue- Removing elements from a queue.
3. Front- get the first item from the queue.
4. Rear- get the last item from the queue.
5. isEmpty/isFull- checks if the queue is empty or full.

6.3 Code
#include<stdio.h>
# define MAX 5
int cqueue_arr[MAX];
int front = -1, rear = -1;
void insert(int item)
{
if((front = = 0 && rear = = MAX-1) || (front = = rear+1))

23
{
printf("Queue Overflow \n");
return;
}
if(front = = -1)
front = rear = 0;
else
{
if(rear = = MAX-1)
rear = 0;
else
rear = rear+1;
}
cqueue_arr[rear] = item ;
}
void deletion()
{
if(front = = -1)
{
printf("Queue Underflow\n");
return ;
}
printf("Element deleted from queue is : %d\n",cqueue_arr[front]);
if(front = = rear)
front = rear = -1;
else
{
if(front = = MAX-1)
front = 0;
else

24
front = front+1;
}
}
void display()
{
int front_pos = front, rear_pos = rear;
if(front = = -1)
{
printf("Queue is empty\n"); return;
}
printf("Queue elements \n");
if( front_pos <= rear_pos )
while(front_pos <= rear_pos)
{
printf("%d ", cqueue_arr[front_pos]);
front_pos++;
}
else
{
while(front_pos <= MAX-1)
{
printf("%d ", cqueue_arr[front_pos])
front_pos++;
}
front_pos = 0;
while(front_pos <= rear_pos)
{
printf("%d ", cqueue_arr[front_pos]);
front_pos++;
}

25
}
printf("\n");
}
int main()
{
int choice, item;
do
{
printf("1.Insert\n");
printf("2.Delete\n");
printf("3.Display\n");
printf("4.Quit\n");
printf("Enter your choice : ");
scanf("%d", &choice);
switch(choice)
{
case 1 :
printf("Input the element for insertion in queue : ");
scanf("%d", &item);
insert(item); break;
case 2 :
deletion(); break;
case 3:
display(); break;
case 4: exit(0);
break;
default:
printf("Wrong choice\n");
}
}while(choice!=4);

26
return 0;
}

6.4 Output

Enter your choice : 1

Input the element for insertion in queue : 6

1. Insert
2. Delete
3. Display
4. Quit

Enter your choice : 1

Input the element for insertion in queue : 4

1. Insert
2. Delete
3. Display
4. Quit

Enter your choice : 3

Queue elements

6 4

1. Insert
2. Delete
3. Display
4. Quit

Enter your choice : 2

Element deleted from queue is 6

27
PROGRAM -07

7.1 Objective: Write a C program to implement Stack using Linked List.


7.2 Theory
A stack can be easily implemented using linked list. A stack contains a top pointer, which is
“head” of the stack where pushing and popping items happens at the head of the list. First
node have null in link field and second node link have first node address in link field and so
on and last node address in “top” pointer. When we implement stack using array, we have
certain problems:

1. We have to create an array of predefined size at compile time.


2. If we create a very large array, we will be wasting a lot of memory space.

So to solve this we try to implement stack using Linked list.

struct node{
int data;
struct node *next;
};

7.3 Code
#include<stdio.h>
#include<conio.h>
struct Node
{
int data;
struct Node *next;
}*top = NULL;
void push(int);
void pop();
void display();
void main()
{

28
int choice, value;
clrscr();
printf("\n:: Stack using Linked List ::\n");
while(1){
printf("\n****** MENU ******\n");
printf("1. Push\n2. Pop\n3. Display\n4. Exit\n");
printf("Enter your choice: ");
scanf("%d",&choice);
switch(choice){
case 1: printf("Enter the value to be insert: ");
scanf("%d", &value);
push(value); break;
case 2: pop(); break;
case 3: display(); break;
case 4: exit(0);
default: printf("\nWrong selection!!! Please try again!!!\n");
}
} }
void push(int value)
{
struct Node *newNode;
newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = value;
if(top == NULL)
newNode->next = NULL;
else
newNode->next = top;
top = newNode;
printf("\nInsertion is Success!!!\n");
}
void pop()
{
if(top == NULL)
printf("\nStack is Empty!!!\n");

29
else{
struct Node *temp = top;
printf("\nDeleted element: %d", temp->data);
top = temp->next;
free(temp);
}
}
void display()
{
if(top == NULL)
printf("\nStack is Empty!!!\n");
else{
struct Node *temp = top;
while(temp->next != NULL){
printf("%d--->",temp->data);
temp = temp -> next;
}
printf("%d--->NULL",temp->data);
}
}
7.4 Output

30
PROGRAM -08

8.1 Objective: Write a C program to implement Queue using Linked List.

8.2 Theory
The main advantage of using linked list over an arrays is that it is possible to implement a
stack/queue that can shrink or grow as much as needed. In using array will put a restriction to
the maximum capacity of the array which can lead to overflow condition. Here, each new
node will be dynamically allocated. So, overflow is not possible. In linked list
implementation of a queue, the last inserted node is always pointed by 'rear' and the first node
is always pointed by 'front'.

8.3 Code
#include<stdio.h>
#include<conio.h>
struct Node
{
int data;
struct Node *next;
}*front = NULL,*rear = NULL;

void insert(int);
void delete();
void display();

void main()
{
int choice, value;
clrscr();

31
printf("\n:: Queue Implementation using Linked List ::\n");
while(1){
printf("\n****** MENU ******\n");
printf("1. Insert\n2. Delete\n3. Display\n4. Exit\n");
printf("Enter your choice: ");
scanf("%d",&choice);
switch(choice){
case 1: printf("Enter the value to be insert: ");
scanf("%d", &value);
insert(value);
break;
case 2: delete(); break;
case 3: display(); break;
case 4: exit(0);
default: printf("\nWrong selection!!! Please try again!!!\n");
}
}
}
void insert(int value)
{
struct Node *newNode;
newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = value;
newNode -> next = NULL;
if(front == NULL)
front = rear = newNode;
else{
rear -> next = newNode;
rear = newNode;
}
printf("\nInsertion is Success!!!\n");
}
void delete()
{

32
if(front == NULL)
printf("\nQueue is Empty!!!\n");
else{
struct Node *temp = front;
front = front -> next;
printf("\nDeleted element: %d\n", temp->data);
free(temp);
} }
void display()
{
if(front == NULL)
printf("\nQueue is Empty!!!\n");
else{
struct Node *temp = front;
while(temp->next != NULL){
printf("%d--->",temp->data);
temp = temp -> next;
}
printf("%d--->NULL\n",temp->data);
} }
8.4 Output

33
PROGRAM -09
9.1 Objective: Write a C program to implement Circular Queue using Linked List.

9.2 Theory

Operations on Circular Queue:


Front: Get the front item from queue.

Rear: Get the last item from queue.

enQueue(value): To insert an element into the circular queue at Rear position.


1. Create a new node dynamically and insert value into it.
2. Check if front==NULL, if it is true then front = rear = (newly created node).
3. If it is false then rear=(newly created node) and rear node always contains the address
of the front node.

deQueue(): To delete an element from the circular queue from front position.
1. Check whether queue is empty or not means front == NULL.
2. If it is empty then display Queue is empty. If queue is not empty then step 3.
3. Check if (front==rear) if it is true then set front = rear = NULL else move the front
forward in queue, update address of front in rear node and return the element.

9.3 Code
#include<stdio.h>
#include<stdlib.h>

typedef struct node{


int data;
struct node *next;

34
}node;
node *createQueue(){
node *rear=NULL,*front=NULL;

printf("How many items you want to create in queue?");


int n,data;
scanf("%d",&n);
int i = 0;

while(i<n){
if(i==0){
printf("Enter the data: ");
scanf("%d",&data);
node *newNode = (node *)malloc(sizeof(node));
newNode->data = data;
newNode->next=NULL;
rear = newNode;
front = rear;
}else{
printf("Enter the data: ");
scanf("%d",&data);
node *newNode = (node *)malloc(sizeof(node));
newNode->data = data;
newNode->next=front;
rear->next=newNode;
rear = newNode;
}
++i;
}

return rear;
}
void display(node *rear, node *front){
if(!rear){
printf("\nNOTHING TO DISPLAY\n");

35
return;
}
node *temp = front;

if(!rear->next){
printf("%d\n",rear->data);
return ; }
if(temp!=rear){

printf("%d ",temp->data);
display(rear, temp->next);
}else{
printf("%d\n",temp->data);
}}
void enqueue(node **rear,int data){
node *newNode = (node *)malloc(sizeof(node));
newNode->data = data;
if(!(*rear)){
newNode->next=NULL;
*rear = newNode;
return;
}
node *temp = *rear;
if(!(*rear)->next){
newNode->next = temp;
}else{
newNode->next = temp->next;
}
temp->next = newNode;

*rear = newNode;
}
int dequeue(node *rear){
int data;
if(!rear){

36
printf("\nNO ITEMS IN THE QUEUE\n");
return 0;
}

if(!rear->next){
data = rear->data;
free(rear);
return data;

}
node *temp = rear->next;
data = temp->data;
rear->next = temp->next;
free(temp);
return data;
}
void main(){
node *rear = createQueue();
display(rear,rear->next);
printf("i am enqueing 99 \next");
enqueue(&rear,99);
display(rear,rear->next);
int data = dequeue(rear);
printf("Delete item is: %d\n",data);
display(rear,rear->next);
}

9.4 Output

37
PROGRAM -10

10.1 Objective: Write C programs to implement


a) traversal operations in a binary tree.
b) Insertion & deletion operations in a binary search tree.

10.2 Binary Tree

10.2.1 Theory

In a normal tree, every node can have any number of children. A binary tree is a special type
of tree data structure in which every node can have a maximum of 2 children. One is known
as a left child and the other is known as right child. There is no need to maintain the order of
nodes basing on their values. In a binary tree, the elements are arranged in the order they
arrive at the tree from top to bottom and left to right .

A Binary Tree node contains the following parts.


1. Data
2. Pointer to left child
3. Pointer to right child

1
/ \
2 3
/
4
Insertion in a binary tree
The idea is to do an iterative level order traversal of the given tree using queue. If we find a
node whose left child is empty, we make a new key as the left child of the node. Else if we
find a node whose right child is empty, we make the new key as the right child. We keep
traversing the tree until we find a node whose either left or right child is empty.

Deletion in a binary tree


Given a binary tree, delete a node from it by making sure that the tree shrinks from the
bottom (i.e. the deleted node is replaced by the bottom-most and rightmost node). Here we do
not have any order among elements, so we replace them with the last element.

10.2.2. Code

#include<stdlib.h>
#include<stdio.h>
struct bin_tree {
int data;
struct bin_tree * right, * left;
};

38
typedef struct bin_tree node;

void insert(node ** tree, int val)


{
node *temp = NULL;
if(!(*tree))
{
temp = (node *)malloc(sizeof(node));
temp->left = temp->right = NULL;
temp->data = val;
*tree = temp;
return;
}

if(val < (*tree)->data)


{
insert(&(*tree)->left, val);
}
else if(val > (*tree)->data)
{
insert(&(*tree)->right, val);
}

void print_preorder(node * tree)


{
if (tree)
{
printf("%d\n",tree->data);
print_preorder(tree->left);
print_preorder(tree->right);
}

}
void print_inorder(node * tree)
{
if (tree)
{
print_inorder(tree->left);
printf("%d\n",tree->data);
print_inorder(tree->right);
}
}

void print_postorder(node * tree)


{
if (tree)
{
print_postorder(tree->left);

39
print_postorder(tree->right);
printf("%d\n",tree->data);
}
}

void deltree(node * tree)


{
if (tree)
{
deltree(tree->left);
deltree(tree->right);
free(tree);
}
}

node* search(node ** tree, int val)


{
if(!(*tree))
{
return NULL;
}

if(val < (*tree)->data)


{
search(&((*tree)->left), val);
}
else if(val > (*tree)->data)
{
search(&((*tree)->right), val);
}
else if(val == (*tree)->data)
{
return *tree;
}
}

void main()
{
node *root;
node *tmp;
//int i;
root = NULL;
/* Inserting nodes into tree */
insert(&root, 9);
insert(&root, 4);
insert(&root, 15);
insert(&root, 6);
insert(&root, 12);
insert(&root, 17);
insert(&root, 2);

40
/* Printing nodes of tree */
printf("Pre Order Display\n");
print_preorder(root);

printf("In Order Display\n");


print_inorder(root);

printf("Post Order Display\n");


print_postorder(root);
/* Search node into tree */
tmp = search(&root, 4);
if (tmp)
printf("Searched node=%d\n", tmp->data);
else
printf("Data Not found in tree.\n");
/* Deleting all nodes of tree */
deltree(root);
}

10.2.3 Output

Pre Order Display


9
4
2
6
15
12
17

In Order Display
2
4
6
9
12
15
17

Post Order Display


2
6
4
12
17
15
9

Searched node=4

41
10.3 Binary Search Trees (BST)

10.3.1 Theory

To enhance the performance of binary tree, we use a special type of binary tree known
as Binary Search Tree. Here, all the nodes in the left subtree of any node contains smaller
values and all the nodes in the right subtree of any node contains larger values.
The following operations are performed on a binary search tree:
1. Search
2. Insertion
3. Deletion (leaf node, node with one child, node with two children)

10.3.2 Code
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

//Represent a node of binary tree


struct node{
int data;
struct node *left;
struct node *right;
};

//Represent the root of binary tree


struct node *root= NULL;

//createNode() will create a new node


struct node* createNode(int data){
//Create a new node
struct node *newNode = (struct node*)malloc(sizeof(struct node));
//Assign data to newNode, set left and right children to NULL
newNode->data= data;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}

42
//insert() will add new node to the binary search tree
void insert(int data) {
//Create a new node
struct node *newNode = createNode(data);

//Check whether tree is empty


if(root == NULL){
root = newNode;
return;
}
else {
//current node point to root of the tree
struct node *current = root, *parent = NULL;

while(true) {
//parent keep track of the parent node of current node.
parent = current;

//If data is less than current's data, node will be inserte


d to the left of tree
if(data < current->data) {
current = current->left;
if(current == NULL) {
parent->left = newNode;
return;
}
}
//If data is greater than current's data, node will be inserted t
o the right of tree
else {
current = current->right;

if(current == NULL) {
parent->right = newNode;
return;
}
}
}
}
}

//minNode() will find out the minimum node


struct node* minNode(struct node *root) {
if (root->left != NULL)
return minNode(root->left);
else
return root;
}

43
//deleteNode() will delete the given node from the binary search tree
struct node* deleteNode(struct node *node, int value) {
if(node == NULL){
return NULL;
}
else {
//value is less than node's data then, search the value in left
subtree
if(value < node->data)
node->left = deleteNode(node->left, value);

//value is greater than node's data then, search the value in r


ight subtree
else if(value > node->data)
node->right = deleteNode(node->right, value);
//If value is equal to node's data that is, we have found the node
to be deleted
else {
//If node to be deleted has no child then, set the node to
NULL
if(node->left == NULL && node->right == NULL)
node = NULL;

//If node to be deleted has only one right child


else if(node->left == NULL) {
node = node->right;
}

//If node to be deleted has only one left child


else if(node->right == NULL) {
node = node->left;
}

//If node to be deleted has two children node


else {
//then find the minimum node from right subtree
struct node *temp = minNode(node->right);
//Exchange the data between node and temp
node->data = temp->data;
//Delete the node duplicate node from right subtree
node->right = deleteNode(node->right, temp->data);
}
}
return node;
}
}

44
//inorder() will perform inorder traversal on binary search tree
void inorderTraversal(struct node *node) {

//Check whether tree is empty


if(root == NULL){
printf("Tree is empty\n");
return;
}
else {

if(node->left!= NULL)
inorderTraversal(node->left);
printf("%d ", node->data);
if(node->right!= NULL)
inorderTraversal(node->right);

}
}

int main()
{
//Add nodes to the binary tree
insert(50);
insert(30);
insert(70);
insert(60);
insert(10);
insert(90);
printf("Binary search tree after insertion: \n");
//Displays the binary tree
inorderTraversal(root);

struct node *deletedNode = NULL;


//Deletes node 90 which has no child
deletedNode = deleteNode(root, 90);
printf("\nBinary search tree after deleting node 90: \n");
inorderTraversal(root);

//Deletes node 30 which has one child


deletedNode = deleteNode(root, 30);
printf("\nBinary search tree after deleting node 30: \n");
inorderTraversal(root);

//Deletes node 50 which has two children


deletedNode = deleteNode(root, 50);

45
printf("\nBinary search tree after deleting node 50: \n");
inorderTraversal(root);

return 0;
}

10.3.3 Output:

Binary search tree after insertion:


10 30 50 60 70 90
Binary search tree after deleting node 90:
10 30 50 60 70
Binary search tree after deleting node 30:
10 50 60 70
Binary search tree after deleting node 50:
10 60 70

46

You might also like